我有一个像这样的结构
typedef struct person {
int id;
char name[20];
} Person;
然后,在函数之外,我有一个指向这些结构的指针数组,就像这样
Person **people;
然后在函数中我将这些人添加到数组中(在循环中)
Person person;
for (i = 0; i < 50; i++)
{
person.id = i;
person.name = nameArray[i];
people[i] = &person;
}
person
正被添加到people
数组中,但是当(在VS2010中)我转到“监视”屏幕并输入people, 50
时
我只是在每个插槽中看到相同的person
,就像添加下一个人一样,它也会改变以前的所有内容。我在这里做错了什么?
另外,要检索某个人的姓名,这是正确的语法吗?
people[0] -> name;
或者是people[0][0].name
?
谢谢!
答案 0 :(得分:9)
你期待什么?您正在使所有指针指向相同的Person
。当person
超出范围时,数组中的所有指针(都是相同的)将无效并指向释放的内存块。您必须在循环的每次迭代中使用malloc
来分配动态存储并创建Person
,直到free
它才会消失:
for (i = 0; i < 50; i++)
{
Person *person = malloc(sizeof(Person));
person->id = i;
person->name = nameArray[i];
people[i] = person;
/* or:
people[i] = malloc(sizeof(Person));
people[i]->id = i;
people[i]->name = nameArray[i];
it does the same thing without the extra temporary variable
*/
}
// then when you are done using all the Person's you created...
for (i = 0; i < 50; ++i)
free(people[i]);
或者,你可以拥有一个Person
而不是Person*
的数组,而你正在做的事情会起作用:
Person people[50];
Person person;
for (i = 0; i < 50; i++)
{
person.id = i;
person.name = nameArray[i];
people[i] = person; // make a copy
}
通过这种方式,您无需free
任何事情。
答案 1 :(得分:2)
我只是在每个位置都看到同一个“人”......
是的,因为你每次都使用相同的Person
。你重新分配其成员,所以最后的任务分配,你的指针都指向同一块内存。
还要意识到您正在存储具有自动存储持续时间的变量的地址(即,已分配堆栈)。当函数退出并在以后解除引用任何指针时,(可能)将清除该内存将导致未定义的行为。
如果需要在函数中初始化数组并在函数退出时保持有效,则应使用动态分配。
答案 2 :(得分:1)
你必须为每个人分配内存:
for (i = 0; i < 50; i++)
{
people[i] = (person*)malloc(sizeof(person)); // dynamic memory allocation
people[i]->id = i;
people[i]->name = nameArray[i];
}
&person
的地址person
在原始版本中没有变化,所以你有一堆指针指向相同的数据,每次迭代都会改变。
答案 3 :(得分:1)
由于您编写此方法的方式,您已将每个指针初始化为同一个Person实例,请检查:
Person person; // this allocates a single person
for (i = 0; i < 50; i++)
{
person.id = i;
person.name = nameArray[i];
people[i] = &person;
}
您需要做的是动态分配每个人,如下所示:
for (i = 0; i < 50; i++)
{
Person* person = (Person*)malloc(sizeof(Person));
person->id = i;
person->name = nameArray[i];
people[i] = person;
}
完成后不要忘记释放所有内存,所以在代码结束时:
int i;
for (i=0; i<50; i++)
free(people[i]);
free(people);
答案 4 :(得分:0)
您需要确保为每个person
分配空间。您现在的代码只有一个person
结构,您正在重用它,所有这些指针都指向同一个地址。
答案 5 :(得分:0)
其他答案都是正确的。我唯一可以添加的是,除了不创建新的Person
之外,当你应该使用堆时,你也在堆栈上分配它。确保您了解为什么以下对您现有代码的“快速更改”是错误的:
for (i = 0; i < 50; i++)
{
Person person; /* <--- BAD. Make sure you understand why. */
person.id = i;
person.name = nameArray[i];
people[i] = &person;
}
每次使用您创建人物的旧方式创建一个新的Person
。同样,请确保您理解为什么这是错误的,其他答案(使用malloc
)是正确的。