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

C++ 文件分割重組:指針數組未分配內存導致崩潰

     編輯:程式設計綜合問答

錯誤現象

代碼聲明 char **str2 = new char*[32]; 後直接 fread(str2[i], ...),程式崩潰或寫入亂碼。

根本原因

new char*[32] 僅分配了 **32 個指針變量的數組**,每個指針**未指向任何有效內存**。fread 試圖往野指針寫數據,導致未定義行為。

修正:為每個指針分配緩衝區

// 正確分配
char **str2 = new char*[32];
for (int i = 0; i < 32; i++) {
    str2[i] = new char[8192];  // 每塊 8KB = 16 * 4*1024
}

// 讀取數據
FILE *fp2 = fopen("file2.dat", "rb");
for (int i = 0; i < 32; i++) {
    fread(str2[i], 16, 4 * 1024, fp2);  // 讀 8KB
    // fseek(fp2, 0, SEEK_CUR);  // 無意義,刪除
}
// ... 使用 str2 ...

// 釋放內存(雙層釋放)
for (int i = 0; i < 32; i++) {
    delete[] str2[i];  // 先釋放每塊緩衝區
}
delete[] str2;         // 再釋放指針數組
fclose(fp2);

代碼中其他嚴重問題

  1. while (i == 32) break; **永不執行**:for 循環條件 i < 32 保證 i 最大 31,刪除此行。
  2. fseek(fp, 0, SEEK_CUR) **無操作**:偏移 0 當前位置,刪除。
  3. fputs(str3[i], fp1) **錯誤用法**:fputs 寫字串(遇 \0 停止),二進制數據必須用 fwrite。
  4. 寫入邏輯錯亂:fseek(fp1, 8*1024*(i+1), SEEK_SET) 定位後連續寫三塊,會覆蓋/留空,需重新設計交織寫入策略。

重構建議:使用 std::vector 管理內存

#include <vector>
#include <fstream>
#include <cstdint>

const size_t BLOCK_SIZE = 8192;
const int BLOCK_COUNT = 32;

std::vector<std::vector<char>> readBlocks(const char* filename) {
    std::vector<std::vector<char>> blocks(BLOCK_COUNT, std::vector<char>(BLOCK_SIZE));
    std::ifstream in(filename, std::ios::binary);
    for (auto& block : blocks) {
        in.read(block.data(), BLOCK_SIZE);
    }
    return blocks;
}

void interleaveWrite(const char* outFile,
                     const auto& blocks2, const auto& blocks3, const auto& blocks4) {
    std::ofstream out(outFile, std::ios::binary | std::ios::in); // 讀寫模式打開原文件1
    for (int i = 0; i < BLOCK_COUNT; i++) {
        out.seekp(8192 * (i + 1));  // 定位寫入位置
        out.write(blocks3[i].data(), BLOCK_SIZE);
        out.write(blocks2[i].data(), BLOCK_SIZE);
        out.write(blocks4[i].data(), BLOCK_SIZE);
    }
}

核心原則

  • 指針數組 ≠ 二維數組:必須逐行分配內存,或用 new char[32][8192] 連續分配(棧可能不足)。
  • 二進制讀寫用 fread/fwrite/read/write,字串函數 fputs/gets 遇 \0 截斷。
  • RAII 容器(vector/string/unique_ptr)自動管理生命周期,消除手動 delete 洩漏風險。
  • 文件交織寫入需精確計算偏移,建議先在內存組裝完整輸出緩衝區,再一次性寫入。

告別裸指針手動內存管理,用現代 C++ 容器寫出安全、可維護的文件處理代碼。

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