【问题标题】:BadPtr after several iterations多次迭代后的 BadPtr
【发布时间】:2011-12-22 00:41:04
【问题描述】:

C++。它可能是在 Visual Studio 中调试和使用内存的更多问题。

我有一个分析文件列表的程序,当前文件的路径是字符串的串联:名为“文件夹”的 CString 对象和文件名本身(也是 CString)。

但是在第 144 次迭代之后(我确定这个数字不重要),文件夹突然变成了 BadPtr,应用程序因访问冲突而崩溃。为了检查,我创建了一个具有相同目录的 CFileFind 对象,而不是与文件夹连接,而是与 finder.GetRoot() 连接。同样的故事,第 144 次迭代和崩溃。

问题是,我怎样才能保护这个变量的内存(在第 144 次迭代之前就可以了)或跟踪实际写入该位置的函数或其他任何东西来调试这个问题。在循环期间,文件夹变量根本没有改变。实际上它在某个类的私有部分中,并且循环中出现的所有函数都无法访问该私有部分。

代码是这样的(可能有一些错别字,因为我删掉了一些不重要的东西):

typedef map<CString, list< CRect > > metadata;
...
metadata::iterator it=mt.begin();
list< CRect >::iterator it_l;
float i=0;

while(it!=mt.end()){
        if(cur.Load(folder+"\\"+(*it).first+".jpg")){
            it_l=(*it).second.begin();
            i+=1.0;
            while(it_l!=(*it).second.end()){
                cur.buildVector(*it_l);
                cur.printVector(mf,',');
                mf<<",1"<<"\n";
                it_l++;
            }
        }
        it++;
    }

buildVector 收集当前图像的 CRect 对象中的特征,cur.Load 加载图像 itef,printVector 将矢量打印到名为 mf 的流中。 i 计算迭代次数。

更新:我检查了我的代码,注释了除 cur.Load(...) 之外的所有行,但在第 584 次迭代时仍然崩溃。看起来像它的覆盖内存问题。我浏览了 Load 中的所有函数:

    bool Image::Load(CString& path){
     if(!src.IsNull()){ 
        src.Destroy();
     }
     src.Load(path);    
     width=src.GetWidth();
     height=src.GetHeight();
     fillBrightnessMatrix();
     fillGradientMatrices();
     return true;
    }

并发现注释 fillBrightnessMatrix() 会使迭代通过列表末尾而没有任何错误。这个函数是唯一一个对内存起作用的函数,下面是它的代码:

 void Image::fillBrightnessMatrix(){
    const int nPitch = src.GetPitch();

    const unsigned int nWidth = src.GetWidth();
    const unsigned int nHeight = src.GetHeight();
    BYTE * pxPixel = reinterpret_cast<BYTE*>(src.GetBits());


    for(int nY = 0; nY < nHeight; ++nY)
    { 
        for(int nX = 0; nX < nWidth; ++nX)
        {
            pxPixel += 3;
            bright[nX][nY]=((*pxPixel+*(pxPixel+1)+*(pxPixel+2))/3.0)/255.0;
        };

        if(nPitch >= 0)
            pxPixel += nPitch - (nWidth*3);
        else
            pxPixel -= ((nWidth*3) + (nPitch*(-1)));
    };
}

bright 在构造函数中分配,它的 double[500][500]。实际上,我在这段代码中没有看到任何内存泄漏,我做错了什么?

现在调试器指向这一行:

bright[nX][nY]=((*pxPixel+*(pxPixel+1)+*(pxPixel+2))/3.0)/255.0;

说 pxPixel 是一个 BadPtr >.

【问题讨论】:

  • 你的迭代循环是什么样子的?
  • 是多线程程序吗?
  • 在我的问题中添加了代码。多线程?没门!它是使用 c++ 迭代器的单线程程序,仅此而已。它收集数据,仅此而已。
  • 最初的错误可能在我们可以看到的代码范围之外,例如在我们看不到的 buildVector 中。也许那个函数正在践踏一些不应该的内存。
  • 我在问题中添加了唯一直接使用内存的函数。

标签: c++ visual-studio-2008 debugging


【解决方案1】:

我没有看过你的代码,但这闻起来像是有人在他们的数据范围内写东西。要捕捉这样的东西:

  • 让您的循环运行到第 143 次迭代。 (使用条件断点在第 143 次中断。)检查您的文件夹以确保它确实仍然正常。
  • 在其数据的地址上设置数据断点。 (我不知道CString,所以我帮不了你。)
  • 单步执行代码。
  • 当数据断点命中时,查看堆栈以了解发生了什么。

【讨论】:

  • CString 是一个 MFC 类。它太老了,它是在 STL 成为语言的一部分之前完成的。如果你查看他们的 CArray 实现,它使用 memcpy 来复制对象。
  • @DeadMG:我知道它是 MFC,而且我知道它的设计很糟糕。但为什么投反对票?
  • 更令人困惑的是:为什么我的声望选项卡中没有显示这个否决票??
  • 不是我的反对票。我通过错误点击对您投了反对票,然后撤消了它。如果它仍然显示,那就是一个错误。
  • @DeadMG:它现在消失了。仍然。我想我当时看到的是您的反对票,该票已被删除,因此未显示在我的代表标签中。然后一定有一个bug on this page,向我展示了在它消失很久之后的反对票。
猜你喜欢
  • 2011-10-22
  • 2011-07-29
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 2018-01-27
  • 2015-07-11
  • 1970-01-01
相关资源
最近更新 更多