c - 如何在函数内初始化 Struct 指针数组?

标签 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 变大时)。

最佳答案

“大小 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);

Why does the malloc() call in line 11 works fine but in line 8 causes this errors?

因为您分配了一个 Table (size=8),然后尝试像访问 struct table_s (size=16) 一样访问它。您的 array 声明没问题,但在此之前,您尝试将 malloc 返回的指针写入 this_table->arrayOfNodes,该指针位于结构中的偏移量 8(即偏移量 0 是 n,偏移量 8 是 arrayOfNodes)。简而言之,您试图在分配的内存之外进行写入:您只分配了 8 个字节,但您正在写入超过结构的前 8 个字节。

关于c - 如何在函数内初始化 Struct 指针数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50312239/

相关文章:

c - 为什么bluegene/q上的XLC编译器不支持 '-qtm'?

c - 如何使用c中的正则表达式从文件中写入的\t\t读取one\t

c - 带有 struct 2d 数组的 strcmp

c++ - CURL HTTP PUT 编译失败

arrays - 如何轻松访问结构体作为矩阵

c++ - 访问模板类结构类型成员

c - Printf 参数未压入堆栈

c++ - 如何删除这个二维指针数组?制作析构函数

c - c中指向字符串的指针

c - 循环内的结构数组