我(顯然)正在學習 C
我不明白為什么要malloc為新復制的字串分配記憶體(他們在 cs50 記憶體講座中做到了)
#include <stdio.h>
#include <stdlib.h>
int main(){
char *s = "Hi";
char *t; // Why the need for char *t malloc(3) here ??
strcpy(t,s);
printf("%s",t); // prints "Hi"
return 0;
}
uj5u.com熱心網友回復:
第一個宣告:char *s = "Hi";不需要 malloc,因為在編譯時,編譯器將設定s為指向在記憶體中已經有指定位置的字串文字。
第二個宣告:char *t;沒有被分配指向任何東西。您可以將 的內容復制s到t,也許一切都可以正常作業,但是您會將 的內容復制s到t最初指向您的作業系統尚未分配給您的記憶體的某個隨機部分。最有可能導致段錯誤和崩潰。
這就是 malloc 所做的,它請求將多個位元組分配給堆上的程式,然后回傳指向該記憶體起始地址的指標(如果由于任何原因未能分配記憶體,則回傳 NULL),允許如果請求成功,您可以安全地使用它。
uj5u.com熱心網友回復:
您正在做的事情稱為 UB,未定義行為。您應該始終為 strcpy 分配必要的記憶體。
事實上,您甚至還沒有包含 string.h,您的代碼將無法運行,因為 strcpy 將是一個未定義的函式。
即使它以某種方式由于某些錯誤起作用,您也總是會遇到分段錯誤。你只分配了 3 個位元組,所有這些都被占用了。您的代碼是可利用的,并且是惡意輸入的安全漏洞
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main(void)
{
char *e = malloc(3);
char *b;
strcpy(e, "Hi"); // 3 bytes
strcpy(b, e);
fputs(b, stdout);
}
分段錯誤。我們將 3 個位元組寫入 0 個位元組的區域。(strcpy(b, e))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *e = "Hi";
char *b;
strcpy(b, e);
fputs(b, stdout);
}
分段錯誤。一樣。
甚至用 string.h 運行你的代碼,
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(){
char *s = "Hi";
char *t; // Why the need for char *t malloc(3) here ??
strcpy(t,s);
printf("%s",t); // prints "Hi"
return 0;
}
你猜怎么著?分段錯誤。
我很抱歉我的苛刻,但對于 C 用戶來說,這是一個非常重要的新話題,需要學習,因為它會引入安全漏洞和不愉快的編碼體驗。
始終驗證輸入,并始終分配必要的空間。
如果您遇到段錯誤,最好的工具之一是 Valgrind 或 Asan。
Valgrind 您將不得不自己查找,但 Asan 是:
gcc -fsanitize=address filename -o filename -g
這將捕獲所有緩沖區溢位,使您的生活更加愉快。您必須包含 -g,它將您的代碼附加到已編譯的檔案中,以便 Asan 可以告訴您您的程式在哪一行失敗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/383161.html
