【问题标题】:Invisible memory error in C++ sieve codeC++ 筛选代码中的不可见内存错误
【发布时间】:2018-04-05 17:23:34
【问题描述】:

我已经用 C++ 编写了一个非常基本的 Eratosthenes 筛,但是当 n1000000(一百万)时,代码会崩溃。我无法解决问题,现在需要帮助。

#include <iostream>
#include <vector>

using namespace std;

int main(){
    long n = 1000000,i ,j;
    vector<bool> arr(n, true);

    for(i = 2; i * i < n; i++){

        if(arr[i]){
            for(j = i + i; j <= n; j += i){
                arr[j] = false;
            }
        }
    }
    cout << "Made it here." << endl;
    return 0;
}

一些信息:

  • 我使用 x64 mingw (Windows 10) 编译器进行编译。
  • 使用 -O2,禁用没有区别
  • n = 100000n = 10000000 不会出现错误(非常奇怪)并且代码工作正常,因此超过一百万的值不会出现问题,而一百万会出现错误(崩溃)。
  • 代码可以打印"Made it here."
  • 尝试将向量设为全局(考虑本地内存限制问题),但无济于事。
  • 使用 DrMemory 进行调试,它显示一个错误1 total unaddressable access(es),我找不到。

感谢您的帮助。

编辑:来自 Drmemory 的错误描述更详细

Error #1: UNADDRESSABLE ACCESS beyond heap bounds: writing 0x0000000003921608-0x000000000392160c 4 byte(s)

【问题讨论】:

  • @Justin,如果那是错误的话,我会很难过 :(我已经为大事做好了准备,也许这就是我错过它的原因。
  • ^ @Justin 所说的。此外,您可以将初始化语句更改为 j=i*i 而不是 j=i+i
  • 让我感到困惑的是,代码具有相当的确定性,但程序的连续运行有时会出现错误,有时不会。
  • 未定义的行为。当你犯这样的错误时,代码是不确定的。
  • @PaulMcKenzie 同意。

标签: c++ c++11 debugging memory-leaks


【解决方案1】:
for(j = i + i; j <= n; j += i){
    arr[j] = false;

j == n 时会发生什么?您访问arr[n],这是超出范围的,为arr.size() == n

这是未定义的行为。你的程序可能会崩溃,或者它可能会默默地继续,或者它可能会做其他事情。你无法推断会发生什么,因为——根据定义——行为是没有定义的。

【讨论】:

  • 谢谢,这不是我原来的问题,但我还有一个问题,我想检查一下这个程序在它的高峰期使用了多少内存。我知道是可以计算出来的,但是我需要用一些工具来测量,你有什么建议吗?
  • @MaxPaython 我不知道 Dr Memory 有没有那个能力,但是 Unix 上的“等价物”(我听说 Dr Memory 是等价物)是 valgrind,这可以告诉你。也许 Dr Memory 可以选择记录这些信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 2020-10-23
  • 2017-07-26
  • 2014-02-12
  • 1970-01-01
相关资源
最近更新 更多