[英]Dynamically allocating memory for 2d char array
我使用malloc
動態分配2d char數組。 除非我在free()
之前將每個數組索引設置為NULL,否則在嘗試free()
時會出現分段錯誤。 為什么我會出現分段錯誤?
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int nrows = 20; int ncolumns = 10;
char ** arr = malloc(nrows * sizeof(char *));
for(int i = 0; i < nrows; i++)
arr[i] = malloc(ncolumns * sizeof(char));
arr[0] = "string1";
arr[1] = "string2";
// does not work without the following code:
// for(int i = 0; i < 20; i++)
// arr[i] = NULL;
for(int i = 0; i < 20; i++)
free(arr[i]);
free(arr);
return 0;
}
當你這樣做:
arr[0] = "string1";
arr[1] = "string2";
覆蓋arr[0]
和arr[1]
,其中包含從malloc
返回的malloc
地址,以及兩個字符串常量的地址。 這會導致內存泄漏,因為內存不再可訪問。 這也是您在調用free
時崩潰的原因,因為這些變量不再保留已分配內存的地址。
你可能想要做的就是使用strcpy
,它會將字符串文字的內容復制到你分配的內存中。
strcpy(arr[0], "string1");
strcpy(arr[1], "string2");
現在你可以正確free
內存了。
您的代碼沒問題,問題來自於您在此處為數組指定字符串文字 : arr[0] = "string1";
。
因此,您正在使用指向字符串文字的指針替換指向已分配內存的arr[0]
的指針。
對文字的指針受到保護,你不能釋放它們(也不能寫入它們),因為你沒有分配它們。
要解決此問題,請使用strcpy
在已分配的內存中復制文字的值:
strcpy(arr[0], "string1");
strcpy(arr[1], "string2");
=
運算符不復制它只分配指針的字符串。 因此,對於那些數組元素,您的malloced內存不再可訪問,並試圖釋放它是一個未定義的行為,可能會導致段錯誤。
您需要使用strcpy
復制它。
有兩點需要了解:
從malloc獲得的每個資源的規則你必須釋放它。 釋放只是調用自由函數(但我們可以選擇assigne空指針,以確保它被釋放)。
char * a = malloc(255);
免費
free(a);/* this is mandatory */
a = NULL;/* we can add this to the first line */
事實上,你習慣於分配NULL值,有一次你訪問它的值你會有NULL deference錯誤:所以你會知道在哪里找到錯誤
你嘗試做什么:分配一個數組char ** arr = malloc(nrows * sizeof(char *));
你釋放它free(arr);
但你分配了20個char arr[i] = malloc(ncolumns * sizeof(char));
數組arr[i] = malloc(ncolumns * sizeof(char));
你忽略了它的值arr[0] = "string1";
(你松開了malloc返回的值,所以你現在不能釋放arr [0])我們不是在C ++中。 因此堆棧中存儲了“string1”(因此malloc無法釋放它)並且您可以免費調用它。
你可以做什么
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int nrows = 20; int ncolumns = 10;
char ** arr = malloc(nrows * sizeof(char *));
for(int i = 0; i < nrows; i++)
arr[i] = malloc(ncolumns * sizeof(char));
free(arr[0]);//know we can loose it value because it is freed
arr[0] = NULL;// in fact we assign a value just after so this line is useless but is educationnal purpose
free(arr[1]);//know we can loose it value because it is freed
arr[1] = NULL;// in fact we assign a value just after so this line is useless but is educationnal purpose
arr[0] = "string1";
arr[1] = "string2";
// does not work without the following code:
// for(int i = 0; i < 20; i++)
// arr[i] = NULL;
for(int i = 2; i < 20; i++)//we start at 2 because the first two value are on the stack
{
free(arr[i]);
arr[i] = NULL;//this is useless because we will free arr just after the loop)
}
free(arr);
arr = NULL;// this is useless because we exit the end of program
return 0;
}
在free
調用時崩潰是代碼中其他地方不正確的內存管理的標志。 當你將指針設置為NULL
然后free
它時,你不會崩潰,因為C標准§7.22.3.3保證free(NULL)
是良性的:
7.22.3.3自由功能
...如果ptr是空指針,則不會發生任何操作 。 否則,如果參數與先前由內存管理函數返回的指針不匹配,或者如果通過調用free或realloc釋放了空間,則行為未定義。
強調我的。
至於其他的答案已經指出,您要撥打free
上的內存,你沒有明確地分配malloc
-家庭功能(因為你改寫arr[i]
的指針指向字符串常量)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.