C迭代结构坏数据

时间:2016-05-10 08:20:13

标签: c pointers struct sizeof dynamic-memory-allocation

我在while循环中为我的结构添加值。

struct person
{
    char * name;
    char * surname;
    int  age;
    char * email;
};
struct person * tablicaOsob[100];

//for loop
tablicaOsob[i] = createPerson(name, surename, age, email);

数据已正确添加。我通过调试器检查了这个

enter image description here

现在我想迭代tablicaOsob我创建函数

void list_persons(struct person *p, int k)
{
    printf("Lista osob\n");

    int i;
    for(i=0; i<k; i++)
    {
        printf("%s\n", p[i].name );
    }

}

但是当我触发此函数时:list_persons(&tablicaOsob,i);我得到了一些不好的数据。问题出在哪儿。我的编译器说:

main.c:74:17: warning: passing argument 1 of 'list_persons' from incompatible pointer type [enabled by default]
                 list_persons(&tablicaOsob,i);
                 ^
main.c:17:6: note: expected 'struct person *' but argument is of type 'struct person * (*)[100]'
 void list_persons(struct person *p, int k)

编辑:

createPerson()

struct person * createPerson(char * name, char * surename, int age, char * email)
{

    struct person * p = (struct person *) malloc(sizeof(struct person *));

    p->name = name;
    p->surname = surename;
    p->email = email;
    p->age = age;

    return p;

}

3 个答案:

答案 0 :(得分:2)

是的,内存分配问题。你正在为p分配比你需要的更少的内存。之后,访问返回的指针会导致越界内存访问,而内存访问又会调用undefined behavior

在您的代码中,

  struct person * p = (struct person *) malloc(sizeof(struct person *));

您只为“指向对象的指针”的大小分配内存,而不是“对象”本身的大小。你应该写

struct person * p = malloc(sizeof(struct person));

或者,为了更好

struct person * p =  malloc(sizeof*p);

此外,在调用函数时,您应该传递指向结构的指针,如

 list_persons(tablicaOsob[0],i); //tablicaOsob[0]is of type struct person * 

应该完成这项工作,只要i值不会导致越界访问。

那就是Please see this discussion on why not to cast the return value of malloc() and family in C.

答案 1 :(得分:1)

您的createPerson功能完全错误。

  1. 正如Alter Mann和Saurav所提到的那样,你正在做错的初始malloc。

  2. 您还需要为指针namesunameemail分配内存。这是在循环中分配多个人所必需的。您需要为每个字符数组分配strlen(xxx) +1的内存。

  3. 该功能如下所示:

    struct person * createPerson(char * name, char * surename, int age, char * email)
    {
      struct person * p = malloc(sizeof(struct person));
    
      p->name = malloc(strlen(name)+1);
      strcpy(p->name, name);
    
      p->surname = malloc(strlen(surename)+1);
      strcpy(p->surname, surename);
    
      p->email = malloc(strlen(email)+1);
      strcpy(p->email, email);
    
      p->age = age;
    
      return p;
    
    } 
    

答案 2 :(得分:0)

struct person * p = (struct person *) malloc(sizeof(struct person *));

这是错误的,您想为struct预留空间,而不是指向此struct的指针。

更改为

struct person *p = malloc(sizeof(struct person)); /* Don't cast malloc */

struct person *p = malloc(sizeof(*person));

这也是错误的:

list_persons(&tablicaOsob,i);

list_persons期待一个指针,tablicaOsob是一个指针数组,不会将指针数组的地址传递给单个指针,传递其值或只是传递第一个元素。

list_persons(*tablicaOsob,i);