可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I was wondering why the following code isnt't working
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
test = "testingonly";
free(test);
}
After thinking about it my assumption was that first i allocate space for 12 chars in memory but the assignment in the next line creates a char array on the stack and the memory address of that is passed to test. So free() tries to release space on the stack which is not allowed. Is that correct?
So what would be the correct approach to save a string on the heap? Is the following a common way?
int main(int argc, char **argv)
{
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
free(test);
}
回答1:
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.
Instead of changing the pointer test
, you need to copy the string "testingonly"
into the allocated place using e.g. strcpy
or use strdup
. Note that functions like malloc
and strdup
return NULL
if insufficient memory is available, and thus should be checked.
char *test = (char*) malloc(12*sizeof(char));
strcpy(test, "testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
or
char *test = strdup("testingonly");
+-+-+-+-+-+-+-+-+-+-+-+-+
test--->|t|e|s|t|i|n|g|o|n|l|y|0|
+-+-+-+-+-+-+-+-+-+-+-+-+
回答2:
You answered your question already. Essentially , strcpy is the appropriate way of copying string.
回答3:
The first version doesn't create a string on the stack, but you're correct that you're not allowed to free
it after the assignment. String literals are usually stored in constant/read-only sections of memory. The assignment doesn't copy anything, just makes test
point to that area of memory. You cannot free it. You also cannot modify that string.
Your second piece of code is correct and usual. You might want to also look into strdup
if your implementation has that.
回答4:
Well you are correct. Now lets examine first piece of code.
char *test = (char*) malloc(12*sizeof(char));
Above code is no issues.
test = "testingonly";
Here you modified the pointer test
leading to memory leak. And when you try to free you are not freeing actual allocated pointer but one "testingonly" literal pointing to. Literal points to constant memory which cannot be overridden in usual scenarios.
Now about second piece of code, this will work fine as you explicitly copied data from where literal is residing to heap where your test
is pointing.
To your second point yes strcpy
is a usual way. Other ways are 'memcpy' if you are copying raw bytes.
NOTE: Literals are not stored on stack. But you cannot modify location where literals are stored.
回答5:
the code
#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;
}
will work
回答6:
This is for allocating the memory:
char *string;
string = (char *) malloc(15);
This is for saving the data:
strcpy(str, "kavitajain");
printf("String = %s, Address = %u\n", str, str);