2015-10-15 61 views
1

我有一个char **,其被设计成保持和要分配给字符串数组的内存量?

我最初分配使用

char **array = malloc(10); 

并且类似地,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

'char **'是**不是**和数组! – Olaf

+0

你有一个错误的地方。找到它,然后看看是否还有任何问题/误解。 – juanchopanza

+0

'char **'不是,绝对不是一个数组 – Magisch

回答

2
  1. 这将在阵列

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

    分配足够的存储器10点的指针为char(char*)在一个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

如果你想保持10字符串,那么你需要为10char *的分配内存和然后分配内存那些char指针。你分配的10字节的内存(不够10char *的).Allocate这样的 -

char **array = malloc(10*sizeof(char *)); // allocate memory for 10 char *'s 

然后你在做什么 -

array[num] = malloc(strlen(source)+1) // allocate desired memory to each pointer 

- 注意num被初始化,并且不访问外边界指数。

+0

这给10 **指针**给“字符串”,而不是“字符串”本身的空间。 – alk

+0

@alk OP自己正确地分配给他们自己,正如问题中提到的那样(虽然不是问题)。这是他有问题的部分。 – ameyCU

+0

char *的大小?那只是10 * sizeof(数组)? –

3

这条线:

char **array = malloc(10); 

分配10个字节,然而,请记住,一个指针不在大小作为字节相同。

因此,你需要确保你使用的相关类型的大小分配足够大小的数组:

char **array = malloc(10 * sizeof(char*)); 

现在,你有10个指针数组您需要分配内存10个字符串中的每一个,例如不需要

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

这里sizeof(char)但我添加它,使之更加明显如何malloc的作品。

0

首先分配指针数组:

char* (*array)[n] = malloc(sizeof(*array)); 

然后,对于数组中的每一项,个别地分配可变长度字符串:

for(size_t i=0; i<n; i++) 
{ 
    (*array)[i] = malloc(some_string_length); 
} 
+1

建议'some_string_length' - >'some_string_length + 1'。 – chux

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或指向无可写内存的指针或指向某些可写内存的指针。在这三种情况中的任何一种情况下,对该指针存储器的写入是未定义行为(UB)。代码可能会崩溃,可能“起作用”,它简直就是UB。代码不得尝试写入该指针。

要清楚:“没有问题”并不意味着代码是正确的。 C是没有网络的编码。如果代码做错了(UB),那么语言不一定会发现错误。所以遵循安全的编程习惯。