【free() invalid next size】謹慎地在C++的類中存儲指針來方便訪問其他節點


“我跟你們說,你們知道STL容器,vector/string/deque等等,都有個reserve方法嗎?你們一個個地push_back,嫌C++比C慢,怪誰?”

“要像我這樣,預先分配足夠大的空間,這樣push_back的時候才快,明不明白?”

“別老說寫C比寫C++好,因為C代碼怎么運行的都在自己掌控之中,還快,那是因為你們不懂C++。”

----------------------------------------------------------------------------------------------------------------------------------------

#include <cstdio>
#include <vector>
using namespace std;

struct Node
{
    int i = 0;
    Node* next = nullptr;
    Node(int _i) : i(_i) { }
};

const int N = 3;  // 某人以為的"足夠大"的數
vector<Node> odd; // 存放偶數: 0,2,4,6...
// 偶數節點指向比自己大1的奇數節點
vector<Node> even; // 存放奇數: 1,3,5,7...
// 奇數節點指向比自己小1的偶數節點

// 於是對於Node node, 只需調用node.next->i就能實現node.i ^ 1這樣的亦或運算
// [不要考慮這個功能意義在哪]

void init()   // 初始化, 兩個vector都申請"足夠多"的空間
{
    odd.reserve(N);
    even.reserve(N);
}

void add()
{
    if (!even.empty())
    {
        even.push_back(odd.back().i + 1); // 插入2n+1
        odd.push_back(even.back().i + 1); // 插入(2n+1)+1=2n+2
    }
    else
    {
        even.push_back(0);
        odd.push_back(1);
    }
    odd.back().next = &even.back(); // 2n+1指向2n+2
    even.back().next = &odd.back(); // 2n+2指向2n+1
}

void XOR_Simulate()
{
    for (int i = 0; i < 3; i++)
        add();
    printf("%d ^ 1 = %d\n", odd[0].i, odd[0].next->i);
    printf("%d ^ 1 = %d\n", even[0].i, even[0].next->i);
}

int main()
{
    init();
    printf("run XOR_Simulate()\n");
    XOR_Simulate();
    printf("OK, now, run XOR_Simulate() again!\n");
    XOR_Simulate();
    return 0;
}

直接上代碼,貼幾個運行結果

唉,都不想多說了,我今天還就踩了這么弱智的陷阱。只不過在較多的代碼中沒有正確地找到原因。

這種隱藏的錯誤剛開始的時候不會出現什么問題,而到了后面,這顆定時炸彈被引爆的時候,只能手足無措地看着segmentation fault或者由於abort()以錯誤free() invalid next size開頭的一大段Memory Map信息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM