一般情况下:
sizeof (test *)
(指针的大小)不能保证等于(即,这里肯定小于)sizeof (test)
(指针points to的大小;这里是 struct 的大小).
在我的机器上
#include <stdio.h>
typedef struct {
char word[50];
} test;
int main(void)
{
printf("sizeof (test) = %zu\n", sizeof (test));
printf("sizeof (test *) = %zu\n", sizeof (test *));
}
产
sizeof (test) = 50
sizeof (test *) = 8
short分配意味着将没有足够的内存来表示 struct 成员,并且当您耗尽所述内存时,将没有定义的行为.您似乎遇到了问题,并试图通过将每个分配的大小增加三倍来解决这些问题,如示例所示.如果您想要指向三个连续 struct 的指针,这仍然是一个不正确的内存量,但是足够的内存将一个小字符串(例如,strlen(str) < 3 * sizeof (test *)
)复制到这些 struct 中的第一个不太可能导致问题(即,段错误).
在你用int
秒的测试中,同样的错误不太可能引起任何人的注意.再一次,在我的机器上
#include <stdio.h>
int main(void)
{
printf("sizeof (int) = %zu\n", sizeof (int));
printf("sizeof (int *) = %zu\n", sizeof (int *));
}
产
sizeof (int) = 4
sizeof (int *) = 8
在最坏的情况下,使用sizeof (int *)
字节来存储int
对象很可能是内存的过度分配,甚至可能是盈亏平衡.如果你很好奇,你可以判断你的机器,但这并不是特别重要--如果你在正确的表达式上使用sizeof
,你就会有正确的内存量.
其一般形式为
T *foo = malloc(sizeof *foo); // equivalent: sizeof (T)
其中分配的是存储对象本身所需的字节数(不是指向所述对象的指针).如果指针值将分配给数组中的元素,则不会更改.
T *bar[3];
bar[0] = malloc(sizeof *bar[0]); // equivalent: sizeof (T)
对于更具体的问题,可以重新表述为
如何分配一个可能需要改变大小的数组?
答案是从乐观的或其他默认长度开始,并分配足够的内存到malloc
(或calloc
;如果开始长度为零,则从NULL
指针值开始).当空间需求发生变化时,将数组大小调整为realloc
.
这里是一个任意的例子,grows一个数组,一次一个元素.
#include <stdio.h>
#include <stdlib.h>
struct line {
char buf[64];
};
int main(void)
{
size_t length = 0;
struct line *lines = NULL;
struct line current;
while (1) {
printf("> ");
if (!fgets(current.buf, sizeof current.buf, stdin))
break;
void *mem = realloc(lines, sizeof *lines * (length + 1));
if (!mem) {
fputs("Out of memory.\n", stderr);
return 1;
}
lines = mem;
lines[length++] = current;
}
putchar('\n');
for (size_t i = 0; i < length; i++)
fputs(lines[i].buf, stdout);
free(lines);
}
> hello
> world
>
hello
world