我有一个char **,用于保存未知数量的未知长度的字符串
我最初使用
分配了10个字节char **array = malloc(10);
并且类似地,在向此数组添加字符串之前,我分配
array[num] = malloc(strlen(source)+1)
我注意到我的程序在将第6个元素添加到数组
时崩溃了我的问题是,这些数组的内存如何工作?当我分配20个字节时,什么也没发生,但是当我分配30个时,突然可以容纳10个元素。这些都是2-3个字符的字符串。我很难想到重新记忆的条件,例如
if condition{
memoryofarray += x amount
realloc(array, memoryofarray)
}
究竟是什么在char **中使用了内存?我的印象是每个字节对应于它们可以容纳多少行,即malloc(10)将允许该数组容纳10个字符串。我需要知道这一点来建立条件+知道增加分配给数组的内存的数量。
另外,奇怪的是,当我进行malloced时
array[num] = malloc(0)
在为该数组元素分配字符串之前,它没有问题。你不需要至少有大量的字节来存储字符串吗?这让我大为困惑
答案 0 :(得分:3)
这一行:
char **array = malloc(10);
分配10个字节,但请记住,指针的大小与字节大小不同。
因此,您需要确保使用相关类型的大小分配足够大小的数组:
char **array = malloc(10 * sizeof(char*));
现在您有一个包含10个指针的数组,您需要为10个字符串中的每一个分配内存,例如
array[0] = malloc(25 * sizeof(char));
这里不需要sizeof(char)
,但我添加它以使malloc的工作方式更加明显。
答案 1 :(得分:2)
这将为数组中的char(char*
)的10个指针分配足够的内存
char **array = malloc(10*sizeof(array[0]));
在64bit
系统上,char*
的大小为8字节= 64位。 char
的大小通常为1个字节= 8位。
使用sizeof(array[0])
代替sizeof(char*)
的好处是,将来更改array
的类型会更容易。
char**
是指向char
的指针。它可能指向堆中具有指向char
的指针的内存块的开始。类似地,char*
是指向char
的指针,它可能指向堆上char
的内存块的开始。
如果您在分配的内存之外写入,则会得到未定义的行为。如果你很幸运,它可能表现得很好!所以当你这样做的时候:
array[num] = malloc(0);
你可能会随机地从(好)运气中得到分段错误。
您对realloc
的使用是错误的。 realloc
可能必须移动您想要增加其大小的内存块,在这种情况下它将返回一个新指针。像这样使用它:
if (condition) {
memoryofarray += amount;
array = realloc(array, memoryofarray);
}
答案 2 :(得分:2)
如果您想保留10
字符串,则需要为10
char *
和分配内存,然后为char
分配内存指针。你分配10
字节的内存( 10
char *
' s)。像这样分配 -
char **array = malloc(10*sizeof(char *)); // allocate memory for 10 char *'s
然后做你正在做的事情 -
array[num] = malloc(strlen(source)+1) // allocate desired memory to each pointer
note - 注意num
已初始化且无法访问超出范围的索引。
答案 3 :(得分:1)
而不是使用容易出错的样式分配内存
pointer = malloc(n); // or
pointer = malloc(n * sizeof(type_of_pointer));
使用
pointer = malloc(sizeof *pointer * n);
然后
// Bad: certainly fails to allocate memory for 10 `char *` pointers
// char **array = malloc(10);
// Good
char **array = malloc(sizeof *array * 10);
这些数组的内存如何工作?
如果分配的内存不足,则无效。所以第1步:分配足够的内存。
关于array[num] = malloc(0)
。分配0可以返回NULL
或指向无可写存储器的指针或指向某些可写存储器的指针。在3种情况中的任何一种情况下,写入指针存储器都是未定义行为(UB)。代码可能崩溃,可能"工作",它只是UB。代码不得尝试写入该指针。
要明确:"工作没有问题"并不意味着代码是正确的。 C没有网络编码。如果代码做错了(UB),语言没有义务捕获该错误。因此,请遵循安全的编程实践。
答案 4 :(得分:0)
首先分配一个指针数组:
char* (*array)[n] = malloc( sizeof(*array) );
然后对于数组中的每个项目,分别分配可变长度字符串:
for(size_t i=0; i<n; i++)
{
(*array)[i] = malloc( some_string_length );
}