【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信息。

posted @ 2017-04-05 01:33  Harley_Quinn  阅读(2629)  评论(0编辑  收藏  举报