首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言 memcpy 導致段錯誤:字串常量不可寫

     編輯:關於C語言

問題現象

在 Linux 下編譯執行以下程式會發生「段錯誤」,但在某些 Unix 系統卻能正常運行:

int main() {
    char *a = "11111111";
    char *b = "2222222";
    printf("before a:%s b:%s\n", a, b);
    memcpy(a, b, 8);  // 嘗試修改 a 指向的記憶體
    printf("after  a:%s b:%s\n", a, b);
    return 0;
}

根本原因

  • 字串常量存放於唯讀區段:char *a = "..." 讓指標指向程式碼段的常量區,屬於唯讀記憶體。
  • Linux 嚴格執行記憶體保護:寫入唯讀頁會觸發 SIGSEGV(段錯誤)。
  • 舊 Unix 系統對記憶體管理較寬鬆,可能允許寫入,但屬於未定義行為。

正確解決方案

方法一:使用字元陣列(分配於堆疊)

char a[] = "11111111";  // 陣列初始化,內容可修改
char b[] = "2222222";
memcpy(a, b, 8);        // 安全

方法二:動態分配記憶體

char *a = malloc(8);
char *b = malloc(8);
memcpy(a, "00000000", 8);
memcpy(b, "11111111", 8);
// 使用完畢需 free(a); free(b);

核心觀念釐清

宣告方式儲存位置可修改性
char *p = "abc";唯讀資料段不可修改
char p[] = "abc";堆疊(區域變數)或資料段(全域)可修改
char *p = malloc(N);堆疊可修改,需手動釋放

最佳實務建議

  1. 需要修改字串內容時,永遠使用陣列或 malloc。
  2. 僅需讀取字串常量時,使用 const char * 讓編譯器協助檢查。
  3. 跨平台程式碼不可依賴「寫入字串常量不崩潰」的行為。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved