2015-10-15 64 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),那麼語言不一定會發現錯誤。所以遵循安全的編程習慣。