c - 如何在函数内初始化 Struct 指针数组?
问题描述
我有以下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);
为什么
malloc()
第 11 行的调用可以正常工作,但第 8 行的调用会导致此错误?
因为你分配了一个Table
(size=8),然后尝试访问它,就好像它是一个struct table_s
(size=16)。您的声明array
很好,但在此之前,您尝试写入由malloc
to返回的指针this_table->arrayOfNodes
,该指针位于结构中的偏移量 8 处(即偏移量 0 是n
,偏移量 8 是arrayOfNodes
)。简而言之,您试图在分配的内存之外写入:您只分配了 8 个字节,但您正在写入结构的前 8 个字节。
推荐阅读
- webrtc - WebRTC App 上的带宽和质量控制
- c - '错误:变量的类型不完整'链接问题
- ckeditor - 在 ckeditor 封面中最大化保存在数据输入屏幕上
- c# - Asp.net Core 的 POST 方法将 DateTime.Now 转换为模型绑定上的 Min Date
- c# - 从 UTF16le 转换为 UTF8
- reactjs - Webpack 运行调试器?
- c# - 从 Azure AppService 返回自身的 GET 请求返回 502 Bad Gateway 错误
- html - 在没有jQuery的表格行末尾附加一个元素?(使用 AngularJS)
- c# - 如何以编程方式将按钮控件组织到网格中?
- selenium - Selenium UI 自动化测试的代码覆盖率工具