在c中分配内存并保存字符串

时间:2011-12-22 06:30:05

标签: c string malloc free

我想知道为什么下面的代码不起作用

int main(int argc, char **argv)
{
     char *test = (char*) malloc(12*sizeof(char));
     test = "testingonly";
     free(test);
}

在考虑之后,我的假设是首先在内存中为12个字符分配空间,但是下一行中的赋值在堆栈上创建一个char数组,并将其内存地址传递给test。所以free()尝试释放堆栈上不允许的空间。这是对的吗?

那么在堆上保存字符串的正确方法是什么?以下是一种常见方式吗?

int main(int argc, char **argv)
{
     char *test = (char*) malloc(12*sizeof(char));
     strcpy(test, "testingonly");
     free(test);
}

5 个答案:

答案 0 :(得分:62)

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.

您需要使用以下方法将字符串test复制到已分配的位置,而不是更改指针"testingonly"strcpy或使用strdup。请注意,如果内存不足,mallocstrdup等函数会返回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|
        +-+-+-+-+-+-+-+-+-+-+-+-+

答案 1 :(得分:8)

你已经回答了你的问题。从本质上讲,strcpy是复制字符串的合适方式。

答案 2 :(得分:5)

第一个版本不会在堆栈上创建一个字符串,但是你在分配后不允许free它是正确的。字符串文字通常存储在内存的常量/只读部分中。赋值不会复制任何内容,只需使test指向该内存区域。你不能释放它。您也无法修改该字符串。

你的第二段代码是正确和平常的。如果您的实现具有此功能,您可能还需要查看strdup

答案 3 :(得分:4)

你是对的。现在让我们检查第一段代码。

char *test = (char*) malloc(12*sizeof(char));

以上代码没有问题。

test = "testingonly";

在这里,您修改了导致内存泄漏的指针test。当你试图释放时,你不会释放实际分配的指针,而是一个“testingonly”字面指向。 Literal指向常量内存,在通常情况下无法覆盖。

现在关于第二段代码,当你明确地从文字位于你test所指向的堆的位置复制数据时,这将正常工作。

对于你的第二点,是strcpy是通常的方式。如果要复制原始字节,其他方法是“memcpy”。

注意:文字不存储在堆栈中。但是你无法修改存储文字的位置。

答案 4 :(得分:0)

这是用于分配内存:

char *string;
string = (char *) malloc(15);

这是为了保存数据:

strcpy(str, "kavitajain");
printf("String = %s,  Address = %u\n", str, str);