2011-12-22 61 views
21

我想知道为什么下面的代码isnt't工作分配内存和保存串在C

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

考虑这件事后,我的假设是,我第一次在内存12个字符,但在分配分配空间下一行在栈上创建一个char数组,并将其内存地址传递给测试。所以free()试图释放堆栈中不允许的空间。那是对的吗?

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

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

第一溶液示出了经典的内存泄漏;你得到一个指向一些分配的内存的指针,然后当把指针指向字符串文字指向'test'时,它就失去了唯一的引用。此后,没有合法的方式来引用分配的内存 - 泄漏。 – 2011-12-22 06:44:32

+2

永远不要在C中绑定malloc的结果,这是毫无意义的,只能隐藏错误和编译器警告。 – Lundin 2011-12-22 07:37:29

+2

是 - 使用'strcpy'或'strncpy'或'memcpy'。 strncpy比strcpy更好,因为它有助于避免在最多N个字符处复制时出现缓冲区溢出问题。 – 2011-12-22 08:55:29

回答

8

您已回答您的问题。从本质上讲,strcpy是复制字符串的适当方式。

+0

只要你知道在目标字符串中已经分配了合适的内存,并且两个字符串都是空的。 – Dave 2011-12-22 07:55:49

5

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

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

+0

+1为常量/只读部分 – 2011-12-22 07:56:56

+0

'strncpy'不*是'strcpy'的更安全版本。它可以使目标阵列不终止。这很少是正确的解决方案。 – 2011-12-22 08:01:18

+0

@Keith:对,删除了那个引用。 'strdup'虽然很不错(假设你知道你的输入是1.一个有效的C字符串和2.可接受的大小 - 无论你的应用程序是什么)。 – Mat 2011-12-22 08:31:39

4

那么你是正确的。现在让我们来检查第一段代码。

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

上面的代码没有问题。

test = "testingonly"; 

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

现在关于第二段代码,这将工作得很好,因为您明确地将数据从文字所在的地方复制到您的test指向的堆。

你的第二点是strcpy是一种常用的方法。其他方法是'memcpy',如果你正在复制原始字节。

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

+0

+1“这样可以正常工作,因为您明确地将数据从文字所在的位置复制到了测试指向的堆中” – 2011-12-29 13:13:26

57
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| 
     +-+-+-+-+-+-+-+-+-+-+-+-+ 
+4

+1赞赏您的解释。 – dicaprio 2011-12-22 09:04:07

+0

谢谢!!!!大 – 2015-10-27 23:20:01

0

代码

#include <stdio.h> 
int main(int argc, char **argv) 
{ 
    char *test = (char*) malloc(12*sizeof(char)); 
    strcpy(test, "testingonly"); 
    printf("string is: %s\n",test); 
    free(test); 
    return 0; 
} 

将工作

0

这是分配内存:

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

这是用于保存数据:

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