如何在函数内初始化一个Struct指针数组?

时间:2018-05-13 02:27:29

标签: c pointers struct malloc valgrind

我有以下test.h文件:

typedef struct node *Node;
struct node {
    const char *key;
    Node next;
};

typedef struct table_s *Table;
struct table_s {
    int n;
    Node *arrayOfNodes;
};

还有这个test.c文件:

Table new_table() {
    Table thisTable = malloc(sizeof(Table));
    thisTable->n = 2;
    thisTable->arrayOfNodes = malloc(thisTable->n*sizeof(Node));

    //this line is inserted here so I can check that calling malloc() like this actuallt work
    Node *array = malloc(thisTable->n*sizeof(Node)); 

    return thisTable;
}

int main() {

    Table myTable = new_table();

return 0;
}

程序编译并运行,但valgrind.log表示存在错误:

==8275== Invalid write of size 8
==8275==    at 0x40056E: new_table (test.c:8)
==8275==    by 0x40043A: main (test.c:18)
==8275==  Address 0x5204048 is 0 bytes after a block of size 8 alloc'd
==8275==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8275==    by 0x40055A: new_table (test.c:6)
==8275==    by 0x40043A: main (test.c:18)

为什么第11行中的malloc()调用工作正常,但第8行会导致此错误?这使我的这个程序的更大版本不适用于大型条目(当n变大时)。

1 个答案:

答案 0 :(得分:3)

"大小8"是一个线索:它是你系统上指针的大小。你想要分配的是一个对象,而不是一个指针。

sizeof(Node)sizeof(struct node *)相同,sizeof(Table)也存在类似问题。

如果你写了类似的东西,它会起作用:

typedef struct table_s Table, *TablePtr;
...
TablePtr thisTable = malloc(sizeof(Table));

如果你坚持使用这些类型,你可以使用以下常见的malloc成语:

// General form:
//   T *p = malloc(sizeof *p);
// or:
//   T *p = malloc(N * sizeof *p);
Table this_table = malloc(sizeof *this_table);
...
this_table->arrayOfNodes = malloc(thisTable->n * sizeof *this_table->arrayOfNodes);
  

为什么第11行中的malloc()调用正常,但在第8行   导致这个错误?

因为您分配了Table(大小= 8),然后尝试访问它,就像它是struct table_s(大小= 16)一样。您对array的声明很好,但在此之前,您尝试将malloc返回的指针写入this_table->arrayOfNodes,该指针位于结构中的偏移量8处(即偏移0为{{ 1}}和偏移量8是n)。简而言之,您试图在分配的内存之外写入:您只分配了8个字节,但是您要在结构的前8个字节之外写入。