簡體   English   中英

動態分配字符串的內存

[英]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);

如果是,那我以后應該免費嗎? 他們似乎都正常工作。

它是一樣的嗎?

不,不是。


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

上面的代碼將固定地址返回到常量文字"test" 每次調用函數時,這將是相同的地址。

不是 一種動態的記憶分配

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

將打印

1

意思是“真”,返回的兩個地址是相同的。

論“ 常數

為了更好地反映test1()結果的test1() ,最好定義如下:

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

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

上面的代碼將地址返回到已經復制"test"新分配的內存區域。 每次調用該函數時,這將是一個不同的 * 1地址。

* 1:至少“不同”,只要先前調用test2()的結果尚未自由()已編輯

一種動態的內存分配 因此,如果不再需要,它需要調用free()傳入strdup() (內部調用malloc() )返回的地址來解除分配內存。

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

將打印

0

意思是“假”,返回的兩個地址是不同的。

為了完整性:根據上述代碼片段避免泄漏

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

是否可以使用

正式地,兩個片段的代碼都是正確的。

哪一個使用,如果“安全”使用完全取決於用例,在上下文中。

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()返回的字符串的內容,但請確保不要超出分配的內存塊。

使用安全嗎?

是的,除非您嘗試更改字符串。 事實上沒有分配,所以每次你的函數都會返回完全相同的指針到內存中的同一位置。

它是一樣的嗎?

不, strdup()進行分配並返回新分配的內存。

如果是,那我以后應該免費嗎?

它不是,但是你需要在strdup()之后釋放內存。

他們似乎都正常工作

對於printf() ,沒問題,除非你試圖改變那些字符串...你將無法更改char* returnValue = "test"字符串,但是你可以在strdup()之后更改字符串

在這兩種情況下, "test"堆棧中被分配為內存的只讀部分( const char )。

在第一個塊中,返回指向"test"的指針。 如前所述,在函數調用之間,這將始終是相同的值。 由於其只讀屬性,嘗試釋放或修改它,將引發執行錯誤( munmap_chunk(): invalid pointer嘗試釋放時munmap_chunk(): invalid pointer ,嘗試修改時出現分段錯誤 )。

在第二塊,返回一個指針,在的存儲器的分配動態部分。 你有責任使用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;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM