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