簡體   English   中英

使用malloc在C中正確使用/創建動態cstrings?

[英]Properly using/creating dynamic cstrings in C with malloc?

以下代碼總是段錯誤:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3 = "asdf";
  printf("%s\n", test3);

以下代碼不會出現段錯誤:

  char *test3 = (char *) malloc(sizeof(char) * 5);
  test3[0] = 'a';
  test3[1] = 'b';
  test3[2] = 'c';
  test3[3] = 'd';
  test3[4] = '\0';
  printf("%s\n", test3);

我想問題可能是如何將cstring文字分配給動態創建的cstring?

“填充”字符串的正確方法是:

 strcpy(test3, "abcd"); 

但是,我強烈建議你不要使用malloc [和DEFINITELY不要使用(char *) malloc(...) - 因為這樣可以隱藏一些相當討厭的錯誤,這些錯誤會在最短的時刻跳起來咬你,因為bug確實有這樣的傾向 - 你可能正在這樣做,因為你正在編譯你的C代碼作為C ++代碼,這是錯誤的,並教你像這樣的壞習慣]。

使用malloc分配小字符串是一個很大的空間浪費。 您的5個字符的字符串可能有16-32字節的開銷,並將四舍五入為8或16個字節。 所以總共可以使用48個字節來存儲5個字節 - 這是一個很大的空間浪費。

在您的情況下,您不能為字符串值指定“=”。

您需要使用strcpy或sprintf函數。 在程序結束時(或不再使用字符串時)不要忘記釋放它! 例如 :

#define BUFSIZE 5

int main(void) {
    char *test3 = malloc(sizeof(char) * BUFSIZE);
    snprintf(test3,BUFSIZE,"test");
    printf("%s\n", test3);
    free(test3);
    return 0;
}

或者你可以寫:

int main(void) {
    char buf[BUFSIZE] = "test";
    printf("%s\n", buf);
    return 0;
}

其他人(正確地)建議您將字符串復制到分配的內存中。

這就是你的方法是segfaulting的原因:字符串“asdf”是一個字符串文字,在編譯時它存儲在rodata或只讀數據中。 當你的程序嘗試

test3 = "asdf";

它試圖創建一個指向rodata的指針。 C不允許指向rodata,所以你的語句不僅不起作用,而且是seg錯誤。

第二種方法很好,因為你沒有修改指針,而是指向它。

首先,謝謝你對這個問題有一個有趣的皺紋。

我用Eclipse / Microsoft C運行你的代碼並沒有得到分段錯誤,它按預期打印“asdf”。

但是,這並不意味着或暗示您沒有得到分段錯誤。 您的結果意味着檢查編譯器如何實現這兩個語句:

   char *test3 = (char *) malloc(sizeof(char) * 5);

在堆上分配存儲並將指針test3設置為指向該位置。 下一個語句也會更新相同的指針。

   test3 = "asdf";

但是,在這種情況下, test3指向文字“asdf”,其中存儲了文字。 一些編譯器生成一個字符串字符串並將它們存儲在可執行文件中的某個位置,因此對於某些編譯器,這些文字無法修改。

那么為什么編譯器會存儲無法訪問的文字呢? 沒有意義,因此問題是:你使用什么C編譯器? 什么版本的C堅持?

要解決可能是編譯器錯誤,並仍然將test3指向文字,請嘗試? (同樣,C編譯器在實現語言結構的方式和方式方面也有所不同。)

  const char *literal = "asdf";  // also try without a const stmt 
  // other code here
  test3 = literal;

最后,在第二個示例中,正在修改malloc ed的堆上的存儲,並且顯然是可尋址的。

暫無
暫無

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

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