动态分配字符串的内存

时间:2018-01-06 09:46:06

标签: c string dynamic-memory-allocation literals c-strings

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);
如果是的话,那我以后应该免费吗?他们似乎都正常工作。

4 个答案:

答案 0 :(得分:3)

  

是一样的

不,不是。

char * test1() {
  char * returnValue = "test";
  return returnValue;
}  

上面的代码将固定地址返回到常量文字"test"。每次调用该函数时,这将是相同的地址。

动态分配内存

printf("%d\n", test1() == test1());

将打印

1

含义" true",返回的两个地址是相同的。

开" constness "

为了更好地反映test1()结果的常数,最好定义如下:

const char * test1() {
  const char * returnValue = "test";
  return returnValue;
}  
char * test2 {
  char * returnValue = strdup("test");
  return returnValue;
}

上面的代码将地址返回到已复制"test"新分配的内存区域。每次调用该函数时,这将是不同的 * 1 地址。

* 1:"不同"至少,只要先前调用 test2() 的结果不是 free() ed已经

动态分配内存。因此,如果不再需要,则需要调用free()传递strdup()返回的地址(内部调用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);
  

是否可以使用

正式两个片段的代码都是正确的。

使用哪一个以及如果使用"安全"完全取决于用例,在上下文中。

答案 1 :(得分:2)

char* test() {
    char* returnValue = "test";
    return returnValue;
}  
  

使用安全吗?

是的,只要您不是要修改returnValue 字符串文字。字符串文字具有静态存储持续时间,因此它们在程序的整个生命周期中是活动的但是尝试修改字符串文字的内容是未定义的行为。

  

相同
char* test {
    char* returnValue=strdup("test");
    return returnValue;
}

答案是 -

strdup()

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()返回的字符串的内容,但请确保不要超出分配的内存块。

答案 2 :(得分:1)

  

使用安全吗?

是的,除非您尝试更改字符串。实际上没有分配,所以每次你的函数都会返回与内存中相同位置完全相同的指针。

  

相同

不,strdup()进行分配并返回新分配的内存。

  

如果是,那我以后应该免费使用吗?

不是,但是你需要在strdup()之后释放内存。

  

它们似乎都正常工作

对于printf(),没问题,除非您尝试更改这些字符串...您将无法更改char* returnValue = "test"字符串,但您可以在{{{{}}之后更改字符串1}}

答案 3 :(得分:0)

在这两种情况下,"test"都在堆栈中分配为内存的只读部分(const char)。

在第一个块中,返回指向"test"的指针。如前所述,在函数调用之间,这将始终是相同的值。由于其只读属性,尝试释放或修改它,会在尝试释放时引发执行错误(munmap_chunk(): invalid pointer,尝试修改时会出现 Segmentation fault

在第二个块中,返回指向中动态分配的内存部分的指针。您有责任使用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;
}