multithreading - MFC 多线程与 delete[] ,dbgheap.c

标签 multithreading mfc

我有一个奇怪的问题,真的不明白发生了什么。

我使用 MFC 多线程类使我的应用程序多线程。

到目前为止一切正常,但现在:

在代码开头的某个地方,我创建了线程:

            m_bucketCreator = new BucketCreator(128,128,32);
    CEvent* updateEvent = new CEvent(FALSE, FALSE);
    CWinThread** threads = new CWinThread*[numThreads];
    for(int i=0; i<8; i++){
        threads[i]=AfxBeginThread(&MyClass::threadfunction, updateEvent);
        m_activeRenderThreads++;
    }

这会创建 8 个线程来处理这个函数:
UINT MyClass::threadfunction( LPVOID params ) //executed in new Thread
{

Bucket* bucket=m_bucketCreator.getNextBucket();

    ...do something with bucket...

delete bucket;

}
m_bucketCreator是静态成员。现在我在尝试删除缓冲区时在 Bucket 的解构函数中遇到了一些线程错误(但是,我理解它的方式应该是这个缓冲区应该在这个线程的内存中,所以我不明白为什么会出现错误)。在 delete[] buffer 的尝试中, 错误发生在 _CrtIsValidHeapPointer()dbgheap.c .

Visual Studio 输出它捕获停止点的消息,这可能是由于堆损坏或因为用户按下 f12(我没有;))
class BucketCreator {
public:
    BucketCreator();

~BucketCreator(void);

void init(int resX, int resY, int bucketSize);

Bucket* getNextBucket(){

Bucket* bucket=NULL;
//enter critical section
CSingleLock singleLock(&m_criticalSection);
singleLock.Lock();

int height = min(m_resolutionY-m_nextY,m_bucketSize);
int width = min(m_resolutionX-m_nextX,m_bucketSize);

bucket = new Bucket(width, height);

//leave critical section
singleLock.Unlock();
return bucket;
}

private:

int m_resolutionX;
int m_resolutionY;
int m_bucketSize;

int m_nextX;
int m_nextY;

//multithreading:
CCriticalSection m_criticalSection;
};

和类桶:
class Bucket : public CObject{
DECLARE_DYNAMIC(RenderBucket)
public:

Bucket(int a_resX, int a_resY){

resX = a_resX;
resY = a_resY;
buffer = new float[3 * resX * resY];

int buffersize = 3*resX * resY; 
for (int i=0; i<buffersize; i++){
    buffer[i] = 0;
}
}

~Bucket(void){
delete[] buffer;
buffer=NULL;
}


int getResX(){return resX;}
int getResY(){return resY;}
float* getBuffer(){return buffer;}

private:
int resX;
int resY;
float* buffer;

Bucket& operator = (const Bucket& other) { /*..*/}
Bucket(const Bucket& other) {/*..*/}
};

谁能告诉我这里可能是什么问题?

编辑:这是我从线程调用的另一个静态函数。这样做安全吗?
static std::vector<Vector3> generate_poisson(double width, double height, double min_dist, int k, std::vector<std::vector<Vector3> > existingPoints)
{
    CSingleLock singleLock(&m_criticalSection);
    singleLock.Lock();

    std::vector<Vector3> samplePoints = std::vector<Vector3>();

            ...fill the vector...

            singleLock.Unlock();
            return samplePoints;
     }

最佳答案

之前的所有回复都是正确的。对于复制构造函数,请确保它不只是复制缓冲区指针,否则会导致问题。它需要分配一个新缓冲区,而不是指针值,这会导致“删除”错误。但我不认为复制构造器会在您的代码中被调用。

我查看了代码,但没有看到任何错误。请注意,在这个 GetNextBucket 代码中甚至不需要线程同步,因为它返回一个局部变量并且这些是线程前的。

发生 ValidateHeapPointer 错误是因为某些东西损坏了堆,当指针写入内存块时会发生这种情况。通常是 for() 循环太过分了,缓冲区分配得不够大,等等。

在调用“delete”期间会报告该错误,因为那是在 Debug模式下验证堆是否存在错误的时候。但是,该错误发生在此之前,只是碰巧只在“新建”和“删除”中检查了堆。此外,它不一定与“桶”类有关。

如果没有使用 BoundsChecker 或 HeapValidator 之类的工具,您需要找到此错误,即注释掉您的代码部分,直到它消失,然后您会发现有问题的代码。

还有另一种方法可以缩小问题的范围。在 Debug模式下,包含在您的代码中,并在不同的兴趣点上调用 _CrtCheckMemory()。当堆损坏时,这将产生错误。只需移动代码中的调用以缩小损坏开始发生的时间点。

我不知道您使用的是哪个版本的 Visual C++。如果您使用的是早期版本,例如 VC++ 6.0,请确保您在编译器选项中使用的是 C 运行时库的 Multitreaded DLL 版本。

关于multithreading - MFC 多线程与 delete[] ,dbgheap.c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1746159/

相关文章:

android - 等待 Android 动画完成

objective-c - 哪个是线程安全的原子或非原子?

c++ - GetThemeFont 函数不工作

mfc - 从 CImageList 中获取 CBitmap

c# - 线程同步 : shared resources and actions with different resource number demand

multithreading - 如何在 Julia 1.0 中使用多线程?

java - 如何制作可以启动和停止的线程之类的东西?

C++ MFC 刷新窗口

c++ - LPBYTE 数据到 MFC 中的 CString

c++ - Visual Studio 2012 : C++ compiler ignoring user-specified include directories