首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C 語言 malloc 返回 void* 需強制轉型、記憶體洩漏風險

     編輯:程式設計綜合問答

錯誤訊息

error C2440: '=' : cannot convert from 'void *' to 'struct stu *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast

原因

C++ 編譯器(VS 預設以 C++ 編譯 `.cpp`)要求 `void*` 轉換為其他指標型別時**必須顯式強制轉型**。C 語言允許隱性轉換,但 C++ 不允許。

修正

// C++ 風格強制轉型 (推薦)
struct stu *student = static_cast(malloc(sizeof(struct stu)));

// 或 C 風格
struct stu *student = (struct stu*)malloc(sizeof(struct stu));

嚴重問題:記憶體洩漏與錯誤處理缺失

  1. 無 `free`**:程式結束前未釋放 `student`,造成洩漏(雖 OS 會回收,但壞習慣)。
  2. 未檢查 `malloc` 返回值**:記憶體不足時返回 `NULL`,解引用導致崩潰。
  3. 結構體定義在函數外**:`struct data`、`struct stu` 應為全域或標頭檔,而非 `main` 內部。

完整修正版

#include 
#include 

struct Data {
    int day, month, year;
};

struct Stu {
    char name[20];
    long num;
    struct Data birthday;
};

int main() {
    struct Stu *student = (struct Stu*)malloc(sizeof(struct Stu));
    if (student == NULL) {
        fprintf(stderr, "記憶體配置失敗\n");
        return 1;
    }

    printf("Input name, number, year, month, day: ");
    if (scanf("%19s", student->name) != 1) goto cleanup;
    if (scanf("%ld", &student->num) != 1) goto cleanup;
    if (scanf("%d %d %d", &student->birthday.year, &student->birthday.month, &student->birthday.day) != 3) goto cleanup;

    printf("\nOutput: name, number, year, month, day\n");
    printf("%-20s %10ld %10d/%02d/%02d\n", 
           student->name, student->num,
           student->birthday.year, student->birthday.month, student->birthday.day);

cleanup:
    free(student);
    return 0;
}

關鍵改進

  • 強制轉型 `malloc` 返回值。
  • 檢查 `malloc`、`scanf` 返回值。
  • 使用 `goto cleanup` 統一釋放資源(C 語言常見模式)。
  • `%19s` 防止緩衝區溢位(留 1 字元給 `\0`)。
  • 結構體名大寫開頭,變數名小寫,風格一致。

現代 C++ 建議

若為 C++ 專案,**完全避免 `malloc`/`free`**,改用 `new`/`delete` 或智慧指標 (`std::unique_ptr`),並用 `std::string` 替代字元陣列。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved