C++使用vector指针触发pointer being freed was not allocated错误
错误原因
你遇到的是典型的悬垂指针(野指针) 访问问题。你没有手动调用free不代表代码里没有内存释放操作:C++中局部栈对象离开作用域时会自动触发析构,std::vector的析构函数会自动释放自身管理的堆内存,底层就会调用free,不需要你手动写代码触发。
具体错误点在int_part函数的分支逻辑里:
if (current_sum == sum) { res.push_back(*xs); vector<int> next_xs; // next_xs是仅在当前if块内有效的局部变量 vector<int>::iterator it = find(xs->begin(), xs->end(), 1); if (it == xs->begin()) return; copy(xs->begin(), it, back_inserter(next_xs)); next_xs[next_xs.size() - 1] -= 1; xs = &next_xs; // 把循环中持续使用的指针指向了块内局部变量 } // 离开if块时,next_xs生命周期结束,内存被自动释放
执行流程的问题点:
- 你把循环中持续使用的
xs指针,指向了if块内部声明的局部vectornext_xs,这个变量的作用域仅限当前if的大括号范围 - 当代码执行完该if分支、进入下一轮while循环时,
next_xs已经被自动析构,对应的内存已经交还给分配器 - 下一轮循环中你再通过
xs调用accumulate、push_back等方法,本质是在访问已经释放的非法内存,malloc检测到违规操作就抛出了你看到的报错。
修复方案
你原本想避免vector多余拷贝的思路没问题,但错误地让指针指向了生命周期更短的栈对象,两种简单的修复方式:
- 最简便:去掉
xs指针,直接把xs定义为while循环外的普通vector<int>对象,需要更新状态时直接修改对象内容即可。C++11之后vector的移动语义开销极低,不会产生你担心的多余大对象拷贝。 - 如果一定要用指针:把
next_xs的定义挪到while循环外层,保证被指向的vector生命周期覆盖整个循环的使用周期,每次更新时直接修改这个外层vector的值即可,不要在块内新建局部变量再取地址赋值给指针。
额外提醒:你的两个打印函数目前都是值传参,调用时会对vector做全量拷贝,如果要优化性能可以改成const引用传参。
内容的提问来源于stack exchange,提问作者Duncan Britt
相关产品推荐
相关产品推荐

