为字符串动态分配内存
Allocating memory for strings dynamically
char* test() {
char* returnValue = "test";
return returnValue;
}
char* test=test();
printf("%s",test);
使用安全吗?和
一样吗
char* test {
char* returnValue=strdup("test");
return returnValue;
}
char* test=test();
printf("%s",test);
如果是,那我应该稍后释放它吗?它们似乎都能正常工作。
is it the same
不,不是。
char * test1() {
char * returnValue = "test";
return returnValue;
}
上面的代码returns固定地址到常量文字"test"
。每次调用该函数时,这将是 相同的 地址。
它是不是内存的动态分配。
正在做
printf("%d\n", test1() == test1());
将打印
1
表示"true",返回的两个地址相同
关于“常量”
为了更好地反映test1()
结果的常量性,最好定义如下:
const char * test1() {
const char * returnValue = "test";
return returnValue;
}
char * test2 {
char * returnValue = strdup("test");
return returnValue;
}
上面的代码 returns 新分配的 内存区域的地址已被复制 "test"
到。每次调用该函数时,这将是一个 不同的*1 地址。
*1:至少"different",只要之前任何调用test2()[的结果=80=] 尚未被 free() 编辑
这个是内存的动态分配。因此,如果不再需要,它需要调用 free()
传递 strdup()
(which internally calls malloc()
) 返回的地址来释放内存。
正在做
printf("%d\n", test2() == test2()); /* leaks memory: 2 times 4+1 char */
将打印
0
表示"false",返回的两个地址不同
为了完整性:按照上面的代码片段避免泄漏
char * p, * q;
printf("%d\n", (p = test2()) == (q = test2()));
free(p);
free(q);
is it saft to use
形式上,两个片段的代码都是正确的。
使用哪个以及是否使用 "safe" 完全取决于用例,取决于上下文。
is it safe to use?
是的,除非您尝试更改字符串。实际上没有分配,所以每次你的函数都会 return 完全相同的指针指向内存中的相同位置。
is it the same, as
不,strdup()
进行了分配并且 return 分配了新的内存。
if yes, then should I free it later on?
不是,不过strdup()
之后你还是需要释放内存。
they are both seem to work correctly
对于 printf()
没问题,除非您尝试更改这些字符串...您将无法更改 char* returnValue = "test"
字符串,但您可以更改之后的字符串strdup()
char* test() {
char* returnValue = "test";
return returnValue;
}
is it safe to use?
是的,只要您不尝试修改 returnValue
,它是一个 字符串文字 。字符串文字具有静态存储持续时间,因此它们 在程序的整个生命周期中都是有效的 但尝试修改字符串文字的内容是未定义的行为。
is it the same, as
char* test {
char* returnValue=strdup("test");
return returnValue;
}
答案是 - 否
Returns a pointer to a null-terminated byte string, which is a duplicate of the string pointed to by str1. The returned pointer must be passed to free to avoid a memory leak.
strdup()
使用malloc()
为新字符串获取内存,这里新字符串为"test"
。 它一直保持分配状态,直到它被显式释放或直到程序结束。因此,完成后应该使用 free()
释放它。此外,您可以修改 strdup()
返回的字符串的内容,但请确保不要访问超出分配的内存块。
在这两种情况下,"test"
在 堆栈 中分配为内存的只读部分 (const char
)。
在第一个块中,您 return 指向 "test"
的指针。如前所述,这在函数调用中始终是相同的值。由于它是只读的 属性,尝试释放或修改它时,将引发执行错误(尝试释放时 munmap_chunk(): invalid pointer
,尝试释放时 Segmentation fault修改).
在第二个块中,您 return 指向 堆 中动态分配的内存部分的指针。您有责任使用 free()
或等效方法释放这部分内存。您可以随意修改这个变量,甚至重新分配这部分内存。
您可以随时进行自己的测试:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* test1() {
char* returnValue = "test";
return returnValue;
}
char* test2() {
char* returnValue = strdup("test");
return returnValue;
}
int main(void)
{
char* vtest1 = test1();
printf("%s => %p\n", vtest1, &vtest1);
char* vtest2 = test2();
printf("%s => %p\n", vtest2, &vtest2);
printf("Freeing 2nd test...\n");
free(vtest2);
printf("Trying to modify 1st test...\n");
vtest1[0] = 'p';
printf("Freeing 1st test...\n");
free(vtest1);
return 0;
}
char* test() {
char* returnValue = "test";
return returnValue;
}
char* test=test();
printf("%s",test);
使用安全吗?和
一样吗char* test {
char* returnValue=strdup("test");
return returnValue;
}
char* test=test();
printf("%s",test);
如果是,那我应该稍后释放它吗?它们似乎都能正常工作。
is it the same
不,不是。
char * test1() {
char * returnValue = "test";
return returnValue;
}
上面的代码returns固定地址到常量文字"test"
。每次调用该函数时,这将是 相同的 地址。
它是不是内存的动态分配。
正在做
printf("%d\n", test1() == test1());
将打印
1
表示"true",返回的两个地址相同
关于“常量”
为了更好地反映test1()
结果的常量性,最好定义如下:
const char * test1() {
const char * returnValue = "test";
return returnValue;
}
char * test2 {
char * returnValue = strdup("test");
return returnValue;
}
上面的代码 returns 新分配的 内存区域的地址已被复制 "test"
到。每次调用该函数时,这将是一个 不同的*1 地址。
*1:至少"different",只要之前任何调用test2()[的结果=80=] 尚未被 free() 编辑
这个是内存的动态分配。因此,如果不再需要,它需要调用 free()
传递 strdup()
(which internally calls malloc()
) 返回的地址来释放内存。
正在做
printf("%d\n", test2() == test2()); /* leaks memory: 2 times 4+1 char */
将打印
0
表示"false",返回的两个地址不同
为了完整性:按照上面的代码片段避免泄漏
char * p, * q;
printf("%d\n", (p = test2()) == (q = test2()));
free(p);
free(q);
is it saft to use
形式上,两个片段的代码都是正确的。
使用哪个以及是否使用 "safe" 完全取决于用例,取决于上下文。
is it safe to use?
是的,除非您尝试更改字符串。实际上没有分配,所以每次你的函数都会 return 完全相同的指针指向内存中的相同位置。
is it the same, as
不,strdup()
进行了分配并且 return 分配了新的内存。
if yes, then should I free it later on?
不是,不过strdup()
之后你还是需要释放内存。
they are both seem to work correctly
对于 printf()
没问题,除非您尝试更改这些字符串...您将无法更改 char* returnValue = "test"
字符串,但您可以更改之后的字符串strdup()
char* test() {
char* returnValue = "test";
return returnValue;
}
is it safe to use?
是的,只要您不尝试修改 returnValue
,它是一个 字符串文字 。字符串文字具有静态存储持续时间,因此它们 在程序的整个生命周期中都是有效的 但尝试修改字符串文字的内容是未定义的行为。
is it the same, as
char* test {
char* returnValue=strdup("test");
return returnValue;
}
答案是 - 否
Returns a pointer to a null-terminated byte string, which is a duplicate of the string pointed to by str1. The returned pointer must be passed to free to avoid a memory leak.
strdup()
使用malloc()
为新字符串获取内存,这里新字符串为"test"
。 它一直保持分配状态,直到它被显式释放或直到程序结束。因此,完成后应该使用 free()
释放它。此外,您可以修改 strdup()
返回的字符串的内容,但请确保不要访问超出分配的内存块。
在这两种情况下,"test"
在 堆栈 中分配为内存的只读部分 (const char
)。
在第一个块中,您 return 指向 "test"
的指针。如前所述,这在函数调用中始终是相同的值。由于它是只读的 属性,尝试释放或修改它时,将引发执行错误(尝试释放时 munmap_chunk(): invalid pointer
,尝试释放时 Segmentation fault修改).
在第二个块中,您 return 指向 堆 中动态分配的内存部分的指针。您有责任使用 free()
或等效方法释放这部分内存。您可以随意修改这个变量,甚至重新分配这部分内存。
您可以随时进行自己的测试:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* test1() {
char* returnValue = "test";
return returnValue;
}
char* test2() {
char* returnValue = strdup("test");
return returnValue;
}
int main(void)
{
char* vtest1 = test1();
printf("%s => %p\n", vtest1, &vtest1);
char* vtest2 = test2();
printf("%s => %p\n", vtest2, &vtest2);
printf("Freeing 2nd test...\n");
free(vtest2);
printf("Trying to modify 1st test...\n");
vtest1[0] = 'p';
printf("Freeing 1st test...\n");
free(vtest1);
return 0;
}