首页 文章

“CRT检测到应用程序在堆缓冲区结束后写入内存”?有没有什么办法解决这一问题?

提问于
浏览
-1

我的编译器一直告诉我“CRT检测到应用程序在堆缓冲区结束后写入内存”?有没有什么办法解决这一问题?

#include <iostream>
#include <iomanip>
#include <cstdlib> 
#include <ctime>
#include <math.h>

using namespace std;

double randomgen(double min, double max) 
{
    double range = (max - min); 
    double div = RAND_MAX / range;
    return min + (rand() / div);
}

void generateWalk(double *data, int n,  double  T,  double  sigma) 
{
 double Delta = sigma*(sqrt(T/n));
 double X;
 data[0] = 0;

 if(randomgen(0,1)<0.5)
 {
 X = Delta;
  for(int i=1; i<=n; i++)
    { 
    data[i] = data[i-1] + X;
    }
  }
 else
 {
  X = -Delta;
  for(int i=1; i<=n; i++)
    { 
    data[i] = data[i-1] + X;
    }
  }
}

void ensembledata(double *data, int nperwalk, int nens, double T,double sigma)
{
    double *storer = new double[nens];
    for (int j=0;j<nens;j++)
    {
        generateWalk(data,nperwalk,T,sigma);
        storer[j]=data[nperwalk-1];

    }
    for (int k=0;k<nens;k++)
    {
        data[k-1]=storer[k-1];
    }
    delete [] storer;                                   
}

void meanvar(double *data,int size, double *mean,double *var)
{
    double sum = 0;
    double *first = data;
    int k = 0;
    for(k = 0; k < size; k++)
        sum += *data++;
    *mean = sum/size;
    sum = 0;
    data = first;
    for(k = 0; k < size; k++)
        sum += (*data - *mean)*(*data++ - *mean);
    *var = sum/(size - 1);
}

int main()
{
    srand((unsigned)time(nullptr));
    double *mdata = new double[1000], mean = 0, var = 0;
    generateWalk(mdata, 1000, 10, 1);and record last position
    ensembledata(mdata, 1000, 1000, 10, 1);
    meanvar(mdata, 1000, &mean, &var);
    cout << fixed << setprecision(3);
    cout << "mean = " << setw(7) << mean << ", var = " << setw(7) << var << endl;
    double sigvals[] = {1,2,3,4,5,6,7,8,9};
    int i = 0;
    for(i = 0; i < 9; i++)
        {
            ensembledata(mdata, 1000, 1000, 10, sigvals[i]);
            meanvar(mdata, 1000, &mean, &var);
            cout << "mean = " << setw(7) << mean << ", var = " << setw(7) << var <<
        ", sigma = " << setw(7) << sigvals[i] << endl;
        }
    delete [] mdata;
    system("PAUSE");
    return EXIT_SUCCESS;
}

我真的不能想到代码中哪种特定的艺术造成了这个问题?

1 回答

  • 0

    修复语法错误(“并记录最后位置”)后,我编译并发出警告:

    g++ -std=c++11 -g -Wall -Wextra    33218861.cpp   -o 33218861
    33218861.cpp: In function ‘void meanvar(double*, int, double*, double*)’:
    33218861.cpp:67:49: warning: operation on ‘data’ may be undefined [-Wsequence-point]
             sum += (*data - *mean)*(*data++ - *mean);
                                                     ^
    

    所以我纠正了这一行

    sum += (*data - *mean)*(*data - *mean); ++data;
    

    然后Valgrind抱怨对无效位置的一些写入:

    ==17852== Invalid write of size 8
    ==17852==    at 0x400D97: generateWalk(double*, int, double, double) (33218861.cpp:35)
    ==17852==    by 0x40103A: main (33218861.cpp:75)
    ==17852==  Address 0x5a1df80 is 0 bytes after a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    ==17852== Invalid write of size 8
    ==17852==    at 0x400D34: generateWalk(double*, int, double, double) (33218861.cpp:27)
    ==17852==    by 0x400E23: ensembledata(double*, int, int, double, double) (33218861.cpp:45)
    ==17852==    by 0x401074: main (33218861.cpp:76)
    ==17852==  Address 0x5a1df80 is 0 bytes after a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    ==17852== Invalid write of size 8
    ==17852==    at 0x400D97: generateWalk(double*, int, double, double) (33218861.cpp:35)
    ==17852==    by 0x400E23: ensembledata(double*, int, int, double, double) (33218861.cpp:45)
    ==17852==    by 0x401074: main (33218861.cpp:76)
    ==17852==  Address 0x5a1df80 is 0 bytes after a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    ==17852== Invalid read of size 8
    ==17852==    at 0x400E8F: ensembledata(double*, int, int, double, double) (33218861.cpp:51)
    ==17852==    by 0x401074: main (33218861.cpp:76)
    ==17852==  Address 0x5a1dfb8 is 8 bytes before a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400DED: ensembledata(double*, int, int, double, double) (33218861.cpp:42)
    ==17852==    by 0x401074: main (33218861.cpp:76)
    ==17852== 
    ==17852== Invalid write of size 8
    ==17852==    at 0x400E92: ensembledata(double*, int, int, double, double) (33218861.cpp:51)
    ==17852==    by 0x401074: main (33218861.cpp:76)
    ==17852==  Address 0x5a1c038 is 8 bytes before a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    mean =  -1.199, var = 10231.199
    ==17852== Invalid write of size 8
    ==17852==    at 0x400D97: generateWalk(double*, int, double, double) (33218861.cpp:35)
    ==17852==    by 0x400E23: ensembledata(double*, int, int, double, double) (33218861.cpp:45)
    ==17852==    by 0x401235: main (33218861.cpp:84)
    ==17852==  Address 0x5a1df80 is 0 bytes after a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    ==17852== Invalid write of size 8
    ==17852==    at 0x400D34: generateWalk(double*, int, double, double) (33218861.cpp:27)
    ==17852==    by 0x400E23: ensembledata(double*, int, int, double, double) (33218861.cpp:45)
    ==17852==    by 0x401235: main (33218861.cpp:84)
    ==17852==  Address 0x5a1df80 is 0 bytes after a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852== 
    ==17852== Invalid read of size 8
    ==17852==    at 0x400E8F: ensembledata(double*, int, int, double, double) (33218861.cpp:51)
    ==17852==    by 0x401235: main (33218861.cpp:84)
    ==17852==  Address 0x5a1ff38 is 8 bytes before a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400DED: ensembledata(double*, int, int, double, double) (33218861.cpp:42)
    ==17852==    by 0x401235: main (33218861.cpp:84)
    ==17852== 
    ==17852== Invalid write of size 8
    ==17852==    at 0x400E92: ensembledata(double*, int, int, double, double) (33218861.cpp:51)
    ==17852==    by 0x401235: main (33218861.cpp:84)
    ==17852==  Address 0x5a1c038 is 8 bytes before a block of size 8,000 alloc'd
    ==17852==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==17852==    by 0x400FE6: main (33218861.cpp:74)
    ==17852==
    

    所以有三条感兴趣的线:27,35和51.你可能会看到第27行出了什么问题:

    for(int i=1; i<=n; i++)
    {
        // Invalid write ... 0 bytes after a block of size 8,000 alloc'd
        data[i] = data[i-1] + X;  // line 27
    }
    

    i<=n 更改为 i<n 会停止在此处运行数组末尾的代码 .

    第35行是类似的 . 第51行有一个不同的问题:

    for (int k=0;k<nens;k++)
    {
        // Invalid read ... 8 bytes before a block of size 8,000 alloc'd
        // Invalid write ... 8 bytes before a block of size 8,000 alloc'd
        data[k-1]=storer[k-1];  // line 51
    }
    

    你可以看到第一次循环,我们访问 data[-1] . 将 k=0 更改为 k=1 可以避免这种情况 . 或许我们需要将 data[k-1]=storer[k-1] 更改为 data[k]=storer[k] 以复制所有值;那里有's insufficient commentary to understand what'的意图 .

    修复这三个问题可以成功完成(除了 system 调用的shell中的消息"PAUSE: not found");我不知道输出是否正确 .

相关问题