我想知道为什么下面的代码不工作
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
test = "testingonly";
free(test);
}
经过思考,我的假设是,首先我在内存中为12个字符分配空间,但下一行的赋值在堆栈上创建了一个字符数组,并将其内存地址传递给测试。所以free()尝试释放堆栈上不允许的空间。对吗?
那么,在堆上保存字符串的正确方法是什么呢?以下是常见的方式吗?int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
free(test);
}
char *test = (char*) malloc(12*sizeof(char));
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|x|x|x|x|x|x|x|x|x|x|x|x| (uninitialized memory, heap)
+-+-+-+-+-+-+-+-+-+-+-+-+
test = "testingonly";
+-+-+-+-+-+-+-+-+-+-+-+-+
test + |x|x|x|x|x|x|x|x|x|x|x|x|
| +-+-+-+-+-+-+-+-+-+-+-+-+
| +-+-+-+-+-+-+-+-+-+-+-+-+
+->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
free(test); // error, because test is no longer pointing to allocated space.
您需要将字符串"testingonly"
复制到分配的位置,而不是更改指针test
,例如使用strcpy
或使用strdup
。注意,如果可用内存不足,malloc
和strdup
这样的函数返回NULL
,因此应该进行检查。
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
或
char *test = strdup("testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
你已经回答了你的问题。从本质上讲,strcpy是复制字符串的合适方式。
第一个版本没有在堆栈上创建字符串,但是你是正确的,你不允许在赋值后对它进行free
。字符串字面值通常存储在内存的常量/只读部分中。这个赋值并没有复制任何东西,只是让test
指向那个内存区域。你无法解放它。也不能修改该字符串。
你的第二段代码是正确的和正常的。你可能还想看看strdup
,如果你的实现有。
你是对的。现在让我们检查第一段代码。
char *test = (char*) malloc(12*sizeof(char));
以上代码没有问题
test = "testingonly";
这里修改了导致内存泄漏的指针test
。当你试图释放你不是释放实际分配的指针,而是一个"testingonly"字面指向。Literal指向通常情况下不能覆盖的常量内存。
现在关于第二段代码,这将工作得很好,因为您显式地将数据从文字所在的位置复制到test
所指向的堆中。
对于你的第二点,是的,strcpy
是一种通常的方式。如果要复制原始字节,还可以使用'memcpy'。
注意:字面量不存储在堆栈中。但是不能修改存储文字的位置。
代码
#include <stdio.h>
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
printf("string is: %sn",test);
free(test);
return 0;
}
可以
这是用来分配内存的:
char *string;
string = (char *) malloc(15);
用于保存数据:
strcpy(str, "kavitajain");
printf("String = %s, Address = %un", str, str);