在C中的结构内更改数组的内容

时间:2014-04-30 08:22:30

标签: c arrays

我目前对这个问题感到难过。

我有这个结构:

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:谢谢大家,解决方案就像一个魅力!很长的问题,一个非常简单的问题,但我很高兴我明白了。非常感谢。

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
    }
}