该程序应该创建一个struct数组,其中包含代码开头的硬编码名称和age数组的名称和年龄值。 我明确要求在main函数中声明数组,然后在insert函数中为它分配内存。程序编译得很好,我应该得到的输出是:
姓名:西蒙
年龄:22
姓名:Suzie
年龄:24
姓名:Alfred
年龄:106
名称:芯片
年龄:6
等。等
然而我得到的输出是这样的:
姓名:西蒙
年龄:22
名称:( null)
年龄:33
姓名:Suzie
年龄:24
名称:( null)
年龄:33
姓名:Suzie
年龄:24
..... 分段错误。
某些名称出现两次,其中一些名称为空,并且在输出结尾处存在分段错误。 任何帮助将不胜感激。非常感谢。
#include <stdio.h>
#include <stdlib.h>
/* these arrays are just used to give the parameters to 'insert',
to create the 'people' array
*/
#define HOW_MANY 7
char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
"Harriet"};
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24};
/* declare your struct for a person here */
struct person {
char *name;
int age;
};
static void insert(struct person **arr, char *name, int age)
{
//initialise nextfreeplace
static int nextfreeplace = 0;
//allocate memory
arr[nextfreeplace] = malloc (sizeof(struct person));
/* put name and age into the next free place in the array parameter here */
arr[nextfreeplace]->name = name;
arr[nextfreeplace]->age = age;
/* modify nextfreeplace here */
nextfreeplace++;
}
int main(int argc, char **argv)
{
/* declare the people array here */
struct person *people;
for (int i = 0; i < HOW_MANY; i++)
{
insert (&people, names[i], ages[i]);
}
/* print the people array here*/
for (int i = 0; i < HOW_MANY; i++)
{
printf("Name: %s \t Age: %i \n", people[i].name, people[i].age);
}
return 0;
}
答案 0 :(得分:2)
在你的代码中,你有
#define HOW_MANY 7
/* ... */
struct person {
/* ... */
};
static void insert(struct person **arr/* ... */) {
static int nextfreeplace = 0;
/* ... */
arr[nextfreeplace] = malloc(sizeof(struct person));
/* ... */
nextfreeplace++;
}
int main(int argc, char **argv) {
/* ... */
struct person *people;
for (int i = 0; i < HOW_MANY; i++) {
insert(&people/* ... */);
}
/* ... */
return 0;
}
问题是您将名为people
的变量定义为指针。然后将该指针的地址传递给insert
。由于局部变量(通常)在堆栈上分配,因此在insert
中进行的分配会覆盖部分变量。
假设你有
struct person *people;
struct person *otherpeople;
然后,当你有nextfreeplace == 0
时,你可以分配到arr[0] == *arr
,这很好。但对于nextfreeplace == 1
,您可以指定arr[1] == *(arr+1) == otherpeople
。
这种类型的错误称为缓冲区溢出。
要修复此错误,您需要使用struct person *people[HOW_MANY];
和insert(people/* ... */);
。
作为旁注:您还应该释放您分配的内存,而不再需要使用free
。