求解LeetCode 204计数质数问题时遇heap-use-after-free错误求助
解决LeetCode 204题的"heap-use-after-free"错误
首先,你的代码里有两个关键问题导致了这个内存错误,咱们一步步拆解清楚:
1. 迭代器失效:遍历vector时修改它
你在for (int d : primes)这个范围for循环里调用了primes.push_back(m),这直接触发了vector的内存危机。vector的底层是连续内存块,当push_back让元素数量超过当前容量时,它会申请一块更大的新内存,把旧元素拷贝过去后立刻释放旧内存。而范围for循环的底层依赖迭代器,此时迭代器已经指向了被释放的旧内存,后续访问就会出现heap-use-after-free——这就是你看到输出里突然冒出来d = 0的原因,程序在访问无效的已释放内存。
2. 逻辑错误:push_back的时机完全不对
你的代码在内层循环(遍历质数除数)的每次迭代后就执行push_back,这完全违背了质数判断的逻辑:只有当所有质数都无法整除m时,才能确定m是质数,再把它加入质数列表。现在的写法会导致还没完成所有除数判断就提前添加元素,既打乱了遍历流程,又可能加入非质数。
修正后的代码
我们把push_back移到内层循环外面,确保只有m通过所有质数的整除测试后,才把它加入primes;同时加了试除法的优化,提升效率:
#include <iostream> #include <vector> using namespace std; int countPrimes(int n) { if (n < 2) return 0; vector<int> primes; primes.push_back(2); for (int m = 3; m < n; m++) { bool isPrime = true; // 遍历已有的质数,判断是否能整除m for (int d : primes) { // 优化:若d的平方大于m,无需继续判断(因数成对存在) if ((long long)d * d > m) { break; } if (m % d == 0) { isPrime = false; break; } } // 确认是质数后再加入列表 if (isPrime) { primes.push_back(m); } } return primes.size(); } int main() { cout << countPrimes(9) << endl; // 输出4,对应质数2、3、5、7 }
测试结果
运行修正后的代码,输入9会输出预期的4,内存错误完全消失,逻辑也符合质数判断的要求。
内容的提问来源于stack exchange,提问作者somerandomdude
相关产品推荐
相关产品推荐

