c - 为什么这个内存地址改变了

标签 c xcode struct

我在 xcode 中使用调试器逐行检查我的代码,最后找到它在哪里中断,因为 c->sets[10] 是 NULL,但我不知道原因。

我声明了三个结构体,line、set 和 cache。

typedef  struct{
    int access_time;
    int tag;
    int valid;
}line;
typedef  struct{
    line *line;
    int empty;
    int insert;

}set;

typedef  struct{
    int set_num;
    int line_num;
    set* sets;
}cache;

我初始化了一个cache,s为4,b为4,E为1,也就是说cache struct中的sets是一个大小为16的数组,每个sets一行。

cache* init(int s, int b, int E){
cache* c =malloc(sizeof(cache)) ;
assert(c!= NULL);
//cache* c;
c->set_num = (1<<s);
c->line_num = E;
c->sets = (set*)malloc(c->set_num*sizeof(c->sets));
assert(c->sets != NULL);
for (int i=0;i<(1<<s);i++){
    c->sets[i].empty=E;
    c->sets[i].line=(line*)malloc(E* sizeof(*c->sets[i].line));
    c->sets[i].insert=0;

    assert(NULL!=c->sets[i].line);
    if (!c->sets[i].line){
        printf("null here");
    }else{
        for (int j=0; j<E;j++){

             c->sets[i].line[j].access_time = 0 ;
            c->sets[i].line[j].valid = 0;
            c->sets[i].line[j].tag = 0;

        }
    }
}
return c;

我有以下代码,set 是 2,tag 是 23456,c 已经用值启动了。

void do_S(cache* c, int set, int tag){


  int i= c->sets[10].line[0].valid;
for(int i=0; i <E;i++ ){

    if (c->sets[set].line[i].valid==1){
        if ( c->sets[set].line[i].tag ==tag )
        {
            hit_count++;
            c->sets[set].line[i].access_time++;
            printf("hit ");
            return;
        }
        }

    }
l10 = c->sets[10].line;
miss_count++;
printf("miss ");
if (c->sets[set].empty==0){
    eviction_count++;
    printf("evict ");
    c->sets[set].line[c->sets[set].insert].tag=tag;
    c->sets[set].line[c->sets[set].insert].valid = 1;
    update_insert(c, set);
}else{
    l10 = c->sets[10].line;
    c->sets[set].empty--;
    l10 = c->sets[10].line; //c->sets[10].line still contains correct value and address is 0x1001043e0  
    c->sets[set].line[c->sets[set].insert].tag = tag;
    c->sets[set].line[c->sets[set].insert].valid = 1;
    l10 = c->sets[10].line; //c->sets[10].line still contains correct value and address is 0x1001043e0

    //update_insert(c,set);
    l10 = c->sets[10].line; //c->sets[10].line becomes NULL address change to 0x0000600a001043e0.


}

}

代码在那里没有做任何事情,但是地址改变了并且 c->sets[10].line 变成了 null。

最佳答案

这个分配不正确:

c->sets = (set*)malloc(c->set_num*sizeof(c->sets));

它为 c->set_num pointers(到集合)分配空间,但你想要的是为 c->set_num 分配空间 < em>设置。那将是这样的:

c->sets = malloc(c->set_num*sizeof(set));

(在 C 中不需要转换结果)或者这样:

c->sets = malloc(c->set_num*sizeof(*c->sets));

因为您没有分配足够的空间,您后来尝试访问超出您分配的空间。由此产生的行为是不确定的,但如果该内存被意外修改也不足为奇,因为它可以很容易地分配给其他一些动态分配的 block 。

关于c - 为什么这个内存地址改变了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29995520/

相关文章:

编译前的 Xcode 4 自定义构建步骤

ios - 如何在 Xcode 中编写涵盖使用 Facebook 登录的 UI 测试?

iphone - 无法在 xcode 中生成 iOS App 存档

c++ - 使用 struct 作为 map 的 KEY 和 VALUE。 find() 操作给出错误

go - 一个结构多个json表示形式

c - 更好地替代 C 中的 exit()、atexit()

c - 使用变长数组生成斐波那契数列代码编译器错误

I/O 文件中的 C do{} while(function(argumen)==1)

c - 处理 C 结构数组

c++ - 将结构复制(使用赋值)到 union 内的结构导致段错误