简体   繁体   English

动态分配字符串的内存

[英]Allocating memory for strings dynamically

char* test() {
    char* returnValue = "test";
    return returnValue;
}  
char* test=test();
printf("%s",test);

is it safe to use? 使用安全吗? is it the same, as 它是一样的吗?

char* test {
    char* returnValue=strdup("test");
    return returnValue;
}
char* test=test();
printf("%s",test);

if yes, then should I free it later on? 如果是,那我以后应该免费吗? they are both seem to work correctly. 他们似乎都正常工作。

is it the same 它是一样的吗?

No, it isn't. 不,不是。


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

The above code returns the fixed address to the constant literal "test" . 上面的代码将固定地址返回到常量文字"test" This will be the same address each time the function is called. 每次调用函数时,这将是相同的地址。

It is not a dynamical allocation of memory . 不是 一种动态的记忆分配

Doing

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

will print 将打印

1

meaning "true", the two addresses returned are the same. 意思是“真”,返回的两个地址是相同的。

On " constness " 论“ 常数

To better reflect the constness of the result of test1() it should better be defined as follows: 为了更好地反映test1()结果的test1() ,最好定义如下:

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

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

The above code returns the address to a freshly allocated area of memory having been copied "test" into. 上面的代码将地址返回到已经复制"test"新分配的内存区域。 This will be a different *1 address each time the function is called. 每次调用该函数时,这将是一个不同的 * 1地址。

*1: "different" at least, as long as the result of any previous call to test2() had not been free() ed already * 1:至少“不同”,只要先前调用test2()的结果尚未自由()已编辑

This is a dynamical allocation of memory . 一种动态的内存分配 It therefore requires a call to free() passing in the address returned by strdup() (which internally calls malloc() ) to deallocated the memory, if not needed any more. 因此,如果不再需要,它需要调用free()传入strdup() (内部调用malloc() )返回的地址来解除分配内存。

Doing

printf("%d\n", test2() == test2()); /* leaks memory: 2 times 4+1 char */

will print 将打印

0

meaning "false", the two addresses returned are different. 意思是“假”,返回的两个地址是不同的。

For completeness: To avoid the leak as per the above snippet do 为了完整性:根据上述代码片段避免泄漏

char * p, * q;
printf("%d\n", (p = test2()) == (q = test2()));
free(p);
free(q);

is it saft to use 是否可以使用

Formally the code of both snippets is correct. 正式地,两个片段的代码都是正确的。

Which one to use and if the use if "safe" completely depends on the use case, on the the context. 哪一个使用,如果“安全”使用完全取决于用例,在上下文中。

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

is it safe to use? 使用安全吗?

Yes, as long as you are not trying to modify the returnValue which is a string literal . 是的,只要您不尝试修改returnValue这是一个字符串文字 The string literals have static storage duration, so they are alive throughout the lifetime of the program but attempt to modify the content of string literal is undefined behavior. 字符串文字具有静态存储持续时间,因此它们在程序的整个生命周期中都是活动的,但是尝试修改字符串文字的内容是未定义的行为。

is it the same, as 它是一样的吗?

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

Answer is - No 答案是 -

strdup() 的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.

The strdup() uses malloc() to obtain memory for the new string, here the new string is "test" . strdup()使用malloc()来获取新字符串的内存,这里新字符串是"test" It stays allocated until it is explicitly deallocated or until the program ends . 它会一直保持分配状态,直到它被明确解除分配或程序结束 So, it should be freed using free() once you are done with it. 因此,一旦完成它就应该使用free()释放它。 Also, you can modify the content of string returned by strdup() but make sure to not to access beyond the allocated memory chunk. 此外,您可以修改strdup()返回的字符串的内容,但请确保不要超出分配的内存块。

is it safe to use? 使用安全吗?

Yes, unless you try to change the string. 是的,除非您尝试更改字符串。 There is no allocation in fact, so each time your function will return exactly the same pointer to the same location in memory. 事实上没有分配,所以每次你的函数都会返回完全相同的指针到内存中的同一位置。

is it the same, as 它是一样的吗?

No, the strdup() makes an allocation and returns new allocated memory. 不, strdup()进行分配并返回新分配的内存。

if yes, then should I free it later on? 如果是,那我以后应该免费吗?

It is no, but still you need to free the memory after strdup() later on. 它不是,但是你需要在strdup()之后释放内存。

they are both seem to work correctly 他们似乎都正常工作

For printf() it is fine, unless you try to change those strings... You will not be able to change the char* returnValue = "test" string, but you will be able to change the string after strdup() 对于printf() ,没问题,除非你试图改变那些字符串...你将无法更改char* returnValue = "test"字符串,但是你可以在strdup()之后更改字符串

In both cases, "test" is allocated in the Stack as a read-only portion of memory ( const char ). 在这两种情况下, "test"堆栈中被分配为内存的只读部分( const char )。

In the first block, you return a pointer to "test" . 在第一个块中,返回指向"test"的指针。 As said before, this will be always the same value across calls to the function. 如前所述,在函数调用之间,这将始终是相同的值。 Due to its read-only property, trying to free or modify it, will raise an execution error ( munmap_chunk(): invalid pointer when trying to free, Segmentation fault when trying to modify). 由于其只读属性,尝试释放或修改它,将引发执行错误( munmap_chunk(): invalid pointer尝试释放时munmap_chunk(): invalid pointer ,尝试修改时出现分段错误 )。

In the second block, you return a pointer to a dynamically allocated portion of memory in the Heap . 在第二块,返回一个指针,在的存储器的分配动态部分。 It's your responsibility to free this portion of memory using free() or equivalent. 你有责任使用free()或同等版本释放这部分内存。 You are free to modify this variable, or even reallocate this portion of memory. 您可以自由修改此变量,甚至可以重新分配这部分内存。

You can always do your own tests: 您可以随时进行自己的测试:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM