You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求解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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:14:14