首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++列表的内存损坏问题

C++列表的内存损坏问题
EN

Stack Overflow用户
提问于 2021-11-01 18:50:41
回答 1查看 139关注 0票数 0

我是c++新手,我需要使用列表容器来实现基于3D标记的分水岭功能。但是当我使用列表容器时,我会发现一些奇怪的错误。我能知道我的密码出了什么问题吗?

非常感谢!

我使用一个列表向量来保存等待搜索像素索引。我以这种方式声明变量(GVInt32int32_t):

代码语言:javascript
复制
vector<list<GVInt32>> toSearchList; 

我使用了这两种列表操作:

  1. 在列表

的末尾添加一个新的等待搜索索引。

代码语言:javascript
复制
toSearchList[cnt].push_back(newidx);

删除列表中间的搜索元素( list<GVInt32>::iterator):为

  1. )

代码语言:javascript
复制
it = toSearchList[cnt].erase(it);

但我有两种错误:

当我做

  1. malloc(): memory corruption toSearchList[cnt].push_back(newidx);

的时候

当我检查调试器中的变量:

时,列表末尾的元素不可访问

代码语言:javascript
复制
[Not accessible elements][1]

https://i.stack.imgur.com/flJg3.png

IDE是QT创建者4.15.2

系统为Ubuntu 18.04

全文代码

watershed_wz.cpp:

代码语言:javascript
复制
#include "watershed_wz.h"

WaterShed_WZ::WaterShed_WZ()
{

}


array<GVInt32, 6> WaterShed_WZ::getNeighbor_WZ(const GVInt32 idx, const GVInt32 width, const GVInt32 height, const GVInt32 thick) {

    GVInt32 SLICE = width * height;
    GVInt32 z = idx / SLICE;
    GVInt32 y = (idx%SLICE) / width;
    GVInt32 x = idx % width;

    array<GVInt32, 6> nIndex;
    nIndex[0] = (x == 0) ? -1 : (idx - 1);
    nIndex[1] = ((x + 1) == width) ? -1 : (idx + 1);
    nIndex[2] = (y == 0) ? -1 : (idx - width);
    nIndex[3] = ((y + 1) == height) ? -1 : (idx + width);
    nIndex[4] = (z == 0) ? -1 : (idx - SLICE);
    nIndex[5] = ((z + 1) == thick) ? -1 : (idx + SLICE);

    return nIndex;
}



void WaterShed_WZ::Watershed3D_WZ(
    const Mat im,
    const GVInt32 width,
    const GVInt32 height,
    const GVInt32 thick,
    GVInt32* label,
    const vector<vector<GVInt32>> marker)
{
    //<Parameter>
    //<image>  the image for watershed
    //<width>  the width of the image
    //<height> the height of the image
    //<thick>  the thick of the image
    //<label>  the map to save result. need to allocate memory before use watershed
    //<marker> the marker's index

//    const GVByte* image=im.data;

    auto t0 = chrono::high_resolution_clock::now();
    QTextStream out(stdout);


//    const GVInt32 SZ_slice = width * height;
//    const GVInt32 SZ = SZ_slice * thick;
    const GVInt32 markerNum = marker.size();

    // create toSearchList. Saved pixel connected to labeled pixels and wait to search
    vector<list<GVInt32>> toSearchList;
    toSearchList.resize(markerNum);

    // set label to INIT (unsearched)
//    ::memset(label, -1, sizeof(GVInt32) * SZ);

    // initialize
    array<GVInt32, 6> nIdx;
    for (size_t i = 0; i < markerNum; i++)
    {
        for (GVInt32 idx : marker[i])
        {
            // initialize label (which can be considered as a map of pointer to labelBar)
            label[idx] = i + 1;
            nIdx = getNeighbor_WZ(idx, width, height, thick);
            for (GVInt32 newidx : nIdx)
            {
                if (newidx != -1)
                {
                    if (label[newidx] == -1) {

                        toSearchList[i].push_back(newidx);

                        label[newidx] = -2;
                    }
                }
            }
        }
    }

    //watershed
    GVByte h;
    GVInt32 idx;
    for (int h_cnt = 0; h_cnt < (1+(int)GV_BYTE_MAX); h_cnt++) // water height
    {
        h = (GVByte)h_cnt;
        for (GVInt32 cnt = 0; cnt < markerNum; cnt++) { // for each marker

            list<GVInt32>::iterator it = toSearchList[cnt].begin();
            while (!toSearchList[cnt].empty())
            {
                // for each pixel connected to the cnt-th labeled region

                idx = *it;
                // if this pixel is higher than water, ignore it
                if (im.at<unsigned char>(idx) > h)
                {
                    ++it;
                    if(it == toSearchList[cnt].end())
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
                // this pixel is lower than water, assign it
                label[idx] = cnt + 1;
//                L.at<int>(idx)=cnt + 1;

                // add new neighbor
                nIdx = getNeighbor_WZ(idx, width, height, thick);
                for (GVInt32 newidx : nIdx)
                {
                    if (newidx != -1)
                    {
                        if (label[newidx]== -1) {
                            toSearchList[cnt].push_back(newidx);
                            label[newidx] = -2;
//                            L.at<int>(newidx)=-2;
                        }
                    }
                }
                // erase searched pixel
                it = toSearchList[cnt].erase(it);

                if(it == toSearchList[cnt].end())
                {
                    break;
                }
                else
                {
                    continue;
                }
            }
        }
    }

    auto t1 = chrono::high_resolution_clock::now();
    auto dt = 1.e-9 * chrono::duration_cast<std::chrono::nanoseconds>(t1 - t0).count();
    out << "Watershed used " << dt << " seconds.\n\n" << Qt::endl;
}

watershed_wz.h:

代码语言:javascript
复制
#ifndef WATERSHED_WZ_H
#define WATERSHED_WZ_H

#define _USE_MATH_DEFINES

#include <vector>
#include <array>
#include <list>
#include <opencv2/core.hpp> //basic building blocks of opencv
#include <opencv2/imgcodecs.hpp> // image io
#include <opencv2/highgui.hpp> //image display
#include <QDebug>
#include <QTextStream>

#include <chrono>

using namespace std;
using namespace cv;

typedef unsigned char          GVByte;
typedef int32_t               GVInt32;
//typedef uint32_t               GVInt32U;

const GVByte              GV_BYTE_MAX = UCHAR_MAX;


class WaterShed_WZ
{
public:
    WaterShed_WZ();
    static array<GVInt32, 6> getNeighbor_WZ(const GVInt32 idx, const GVInt32 width, const GVInt32 height, const GVInt32 thick);
    static void Watershed3D_WZ(
            const Mat im,
            const GVInt32 width,
            const GVInt32 height,
            const GVInt32 thick,
            GVInt32* label,
            const vector<vector<GVInt32>> marker);
};

#endif // WATERSHED_WZ_H
EN

回答 1

Stack Overflow用户

发布于 2021-11-01 19:20:20

尝试删除像这样的任何地方的[cnt]索引

代码语言:javascript
复制
toSearchList[cnt].end() --> toSearchList.end()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69801464

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档