我目前对这个问题感到难过。
我有这个结构:
typedef struct corgi_entry {
unsigned pup; //Supposed to be hex
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
Pcorgi_entry *arrayCorgiHead;
} corgi, *Pcorgi;
我有这些变量:
static corgi c1;
在init函数中,我malloc我的arrayCorgiHead
c1.arrayCorgiHead = (Pcorgi_entry *)malloc(sizeof(Pcorgi_entry) * corgiNumber));
corgiNumber只是一个占位符,但它可以很多,只是索引的大小。
鉴于此,后来我正在运行一个循环。循环的每次迭代,我都从某个地方给出了一个corgi和一个索引。如果在那个索引处它是null,我应该做一个corgi并将pup数据分配给它们。如果它不是空的,我会检查我在索引处给出的小狗,以查看小狗是否匹配。
if(c1.arrayCorgiHead[index] == NULL){
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
}
else{ //Not null
if(c1.arrayCorgiHead[index]->pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index]->pup); //For debug purposes
//Do stuff
}
}
这是问题所在。在我给这段代码的文件中,“外部”索引/ corgis,在我的第三个条目中,我给它与第一个相同:
Index: 1 Corgi{pup = 123}
Index: 2 Corgi{pup = 456}
Index: 1 Corgi{pup = 123}
出于某种原因,当它处理第三个条目时,它表示它不匹配。我在数组索引处打印出corgi pup,我得到一些非常奇怪的数字(9814008或其他东西)。每当我./corgisim和诸如此类的时候,这个随机数就会改变。
除了这里写的内容之外,我不会在任何其他位置触摸阵列。为什么我的数据会在循环迭代后发生变化?
*编辑:为了澄清我的最后一点,我的printf语句
Corgi Made!, pup: 123
Corgi Made!, pup: 456
Corgi Found?, pup: 20138940139 (random number that changes every time I run my program)
为了清楚起见,这段代码已被缩写(并且考虑到,我不知道这是否使事情变得更清楚。我脑中的麻木使我疯了)。正如您从代码中可以看出的那样,我对C不是很熟悉。
谢谢!
编辑2:谢谢大家,解决方案就像一个魅力!很长的问题,一个非常简单的问题,但我很高兴我明白了。非常感谢。
答案 0 :(得分:1)
以下是问题:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
变量newcorgi_entry
是一个局部变量,在堆栈上分配。因此,一旦超出变量的声明范围,就不能依赖&newcorgi_entry
作为有效的内存地址。
以下是解决方案:
您应该在堆上分配corgi_entry
实例:
corgi_entry* newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pup = pupnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
答案 1 :(得分:0)
问题在于你如何分配"存储器:
corgi_entry newcorgi_entry = {pupnumber};
c1.arrayCorgiHead[index] = &newcorgi_entry;
这里,newcorgi_entry
被分配在堆栈上。然后,将该堆栈变量的地址分配给您的数组。问题是,只要你的函数超出范围,任何其他函数都可以使用内存,并且迟早会被其他函数覆盖。
有两种解决方案:使用malloc
在堆上进行分配,或者根本不使用指针。第一个解决方案如下:
Pcorgi_entry newcorgi_entry = malloc(sizeof(corgi_entry));
newcorgi_entry->pub = pubnumber;
c1.arrayCorgiHead[index] = newcorgi_entry;
对于第二种解决方案,有一些变化。这是一个:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry, *Pcorgi_entry;
typedef struct corgi {
corgi_entry *arrayCorgiHead; // "Head" is the wrong name here, IMHO.
} corgi, *Pcorgi;
static corgi c1;
// calloc clears the memory to 0
c1.arrayCorgiHead = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!c1.arrayCorgiHead[index].inUse){
c1.arrayCorgiHead[index].pub = pubNumber
c1.arrayCorgiHead[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
}
else{
if(c1.arrayCorgiHead[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", c1.arrayCorgiHead[index].pup); //For debug purposes
//Do stuff
}
}
我认为corgi
结构及其变量是不必要的。我会这样做:
typedef struct corgi_entry {
unsigned pup;
int inUse;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
if(!corgis[index].inUse){
corgis[index].pub = pubNumber
corgis[index].inUse = 1;
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}
另一种方法是定义" pubNumber" 0
是非法的,所以你可以把它当作哨兵来代替:
typedef struct corgi_entry {
unsigned pup;
} corgi_entry;
static corgi_entry *corgis;
// calloc clears the memory to 0
corgis = (corgi_entry *)calloc(corgiNumber, sizeof(corgi_entry));
// pub number 0 is illegal, so it must be an unused entry
if(corgis[index].pub == 0) {
corgis[index].pub = pubNumber
printf("Corgi Made!, pup: %10x\n", corgis[index].pup); //For debug purposes
}
else{
if(corgis[index].pup != given_corgi_pup){
printf("Corgi Found?, pup: %10x\n", corgis[index].pup); //For debug purposes
//Do stuff
}
}