考虑以下示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_t {
char (*p)[20];
} test;
int main(int argc, char **argv) {
test t;
t.p = malloc(2 * sizeof(*t.p));
strcpy(t.p[0], "hello");
strcpy(t.p[1], "world");
printf("[%s]n", t.p[0]);
printf("[%s]n", t.p[1]);
free(t.p);
}
上述代码不正确,因为malloc
没有为索引为1的元素分配足够的内存。这可以在valgrind下运行时看到。当我从将mallocated内存量增加一倍时
t.p = malloc(2 * sizeof(char *));
至:
t.p = malloc(4 * sizeof(char *));
valgrind输出不再显示内存错误。
我理解错误的原因,但我看不出应该如何计算malloc调用所需的内存。
谢谢。
已编辑:示例代码
t.p
是一个指向20个char
数组的指针:您可以在程序中访问2个这样的数组,因此应该为这些数组分配40个字节。
有一种更简单的方法:将对象p
点的大小分配为数组中元素数量的倍数:
t.p = malloc(sizeof(*t.p) * 2);
这样,如果您更改struct test_t
的定义,malloc
分配的金额将自动调整。
请注意,您的声明是多余的:
memset(&t, 0, sizeof(test));
可以简化为test t = { NULL };
或t.p = NULL;
,或者甚至完全消除,因为malloc
将设置t.p
的值。
strcpy(t.p[0], "hello");
t.p[0][strlen("hello")] = ' '; // useless: the ' ' was alread set there by strcpy
strcpy(t.p[1], "world");
t.p[1][strlen("world")] = ' '; // useless: the ' ' was alread set there by strcpy
整个代码可以简化为:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_t {
char (*p)[20];
} test;
int main(int argc, char **argv) {
test t;
t.p = malloc(sizeof(*t.p) * 2);
strcpy(t.p[0], "hello");
strcpy(t.p[1], "world");
printf("[%s]n", t.p[0]);
printf("[%s]n", t.p[1]);
free(t.p);
return 0;
}