分配值后如何将分配的内存释放给指针数组?
How to free allocated memory to an array of pointers after assigning value?
一个简单的初学者困境,所以应该很快就会明白。
我正在尝试从 char 指针数组中的变量中释放分配的内存
这不会引发错误:
array= malloc(1*sizeof(char *) + 1);
array[0] = malloc(2*sizeof(char *));
free(array[0]);
然而,如果我给它添加一些值,我会得到一个错误:
array= malloc(2*sizeof(char *));
array[0] = malloc(2*sizeof(char *));
array[0] = "a";
free(array[0]);
(malloc: *** error for object 0x10 ......: pointer being freed was not allocated
malloc: *** 在 malloc_error_break 中设置断点进行调试)
如何解释,如何处理?
假设您的 array
是指向 字符串 的指针列表(每个字符串都将获取数据,例如 2 个字符,"a"
), 那么你的方法有几个错误。
首先,array[0]
(和其他元素)应该分配为 sizeof(char) * 2
(而不是 sizeof(char*) * 2
)——这将提供指向缓冲区的指针,每个缓冲区最多可容纳 2 个字符(a
字母和 nul
终止符)。
所以:
array= malloc(2*sizeof(char *)); // An array of two char* pointers
array[0] = malloc(2*sizeof(char)); // One pointer to a 2-character buffer
//...
然后,当您要将给定字符串分配给其中一个元素时,请使用 strcpy
函数,如下所示。您的 array[0] = "a";
行所做的是 将已分配缓冲区的地址 替换为 字符串文字的地址 – 并且,正如您没有分配它,你不能释放它(然后你甚至不能释放你的实际分配的缓冲区,因为你有'lost'它的地址)。
//...
strcpy(array[0], "a"); // Copy the second argument's data to the first
// ... later on ...
free(array[0]); // This will now (still) work, as you didn't change the address
// ...
free(array); // And don't forget to free the array of pointers!
另请注意,sizeof(char)
定义(根据 C 标准)为 1 个字节,因此您可以在第一行的第二行中省略它上面的代码片段(但是在 sizeof(char*)
的情况下你 需要 它——指针的大小会因平台和编译器而异。
@Adrian Mole 完全正确,我只想添加一些关于字符串文字的评论。
字符串常量位于程序的.rodata 段,这是一个预分配的只读段,占用程序内存space。在任何情况下都不能释放或修改该段中的任何值,因此
array[0] = "a";
array[0][0] = array[0][0] + 1;
也会报错
一个简单的初学者困境,所以应该很快就会明白。
我正在尝试从 char 指针数组中的变量中释放分配的内存
这不会引发错误:
array= malloc(1*sizeof(char *) + 1);
array[0] = malloc(2*sizeof(char *));
free(array[0]);
然而,如果我给它添加一些值,我会得到一个错误:
array= malloc(2*sizeof(char *));
array[0] = malloc(2*sizeof(char *));
array[0] = "a";
free(array[0]);
(malloc: *** error for object 0x10 ......: pointer being freed was not allocated malloc: *** 在 malloc_error_break 中设置断点进行调试)
如何解释,如何处理?
假设您的 array
是指向 字符串 的指针列表(每个字符串都将获取数据,例如 2 个字符,"a"
), 那么你的方法有几个错误。
首先,array[0]
(和其他元素)应该分配为 sizeof(char) * 2
(而不是 sizeof(char*) * 2
)——这将提供指向缓冲区的指针,每个缓冲区最多可容纳 2 个字符(a
字母和 nul
终止符)。
所以:
array= malloc(2*sizeof(char *)); // An array of two char* pointers
array[0] = malloc(2*sizeof(char)); // One pointer to a 2-character buffer
//...
然后,当您要将给定字符串分配给其中一个元素时,请使用 strcpy
函数,如下所示。您的 array[0] = "a";
行所做的是 将已分配缓冲区的地址 替换为 字符串文字的地址 – 并且,正如您没有分配它,你不能释放它(然后你甚至不能释放你的实际分配的缓冲区,因为你有'lost'它的地址)。
//...
strcpy(array[0], "a"); // Copy the second argument's data to the first
// ... later on ...
free(array[0]); // This will now (still) work, as you didn't change the address
// ...
free(array); // And don't forget to free the array of pointers!
另请注意,sizeof(char)
定义(根据 C 标准)为 1 个字节,因此您可以在第一行的第二行中省略它上面的代码片段(但是在 sizeof(char*)
的情况下你 需要 它——指针的大小会因平台和编译器而异。
@Adrian Mole 完全正确,我只想添加一些关于字符串文字的评论。 字符串常量位于程序的.rodata 段,这是一个预分配的只读段,占用程序内存space。在任何情况下都不能释放或修改该段中的任何值,因此
array[0] = "a";
array[0][0] = array[0][0] + 1;
也会报错