C - 输出包含空值和分段错误

时间:2017-07-30 14:03:56

标签: c pointers struct malloc

该程序应该创建一个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;
    }

1 个答案:

答案 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