为什么这个内存地址改变了
Why this memory address changed
我在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,每组一行。
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 变为空。
此分配不正确:
c->sets = (set*)malloc(c->set_num*sizeof(c->sets));
它为c->set_num
指针分配space(到集合),但你想要的是space为c->set_num
套。那将是这样的:
c->sets = malloc(c->set_num*sizeof(set));
(在 C 中不需要强制转换结果)或者这样:
c->sets = malloc(c->set_num*sizeof(*c->sets));
因为您没有分配足够的 space,您稍后尝试访问 space 超出您分配的内容。由此产生的行为是不确定的,但如果该内存被意外修改也不足为奇,因为它可以很容易地分配给其他一些动态分配的块。
我在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,每组一行。
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 变为空。
此分配不正确:
c->sets = (set*)malloc(c->set_num*sizeof(c->sets));
它为c->set_num
指针分配space(到集合),但你想要的是space为c->set_num
套。那将是这样的:
c->sets = malloc(c->set_num*sizeof(set));
(在 C 中不需要强制转换结果)或者这样:
c->sets = malloc(c->set_num*sizeof(*c->sets));
因为您没有分配足够的 space,您稍后尝试访问 space 超出您分配的内容。由此产生的行为是不确定的,但如果该内存被意外修改也不足为奇,因为它可以很容易地分配给其他一些动态分配的块。