[英]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.