要分配给字符串数组的内存量?

时间:2015-10-15 14:19:26

标签: c arrays memory memory-management

我有一个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)

在为该数组元素分配字符串之前,它没有问题。你不需要至少有大量的字节来存储字符串吗?这让我大为困惑

5 个答案:

答案 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)

  1. 这将为数组中的char(char*)的10个指针分配足够的内存

    char **array = malloc(10*sizeof(array[0]));
    

    64bit系统上,char*的大小为8字节= 64位。 char的大小通常为1个字节= 8位。

  2. 使用sizeof(array[0])代替sizeof(char*)的好处是,将来更改array的类型会更容易。

  3. char**是指向char的指针。它可能指向堆中具有指向char的指针的内存块的开始。类似地,char*是指向char的指针,它可能指向堆上char的内存块的开始。

  4. 如果您在分配的内存之外写入,则会得到未定义的行为。如果你很幸运,它可能表现得很好!所以当你这样做的时候:

    array[num] = malloc(0);
    

    你可能会随机地从(好)运气中得到分段错误。

  5. 您对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 );
}