由于多个线程中的 free() 调用,程序随机崩溃

Program crashing randomly due to free() call in multiple threads

本文关键字:调用 程序 随机 崩溃 线程 于多个 free      更新时间:2023-10-16

我有一段代码,其中有类似以下内容:

int *mem_ptr;
.
.
if(mem_ptr)
{
    free(mem_ptr);
}
.
.

应用程序是多线程的。有时,发生的情况是一个线程通过if检查,然后在上下文切换发生之前free()另一个线程也通过了if检查并执行free()。现在,当控件返回到第一个线程时,它会在free()崩溃,从而Abort message: 'invalid address or address of corrupt block 0x40735cb0 passed to dlfree'错误。

除了互斥锁,有没有更好的方法来处理这种情况

PS :我正在C++中研究Android本机绑定器,这段代码在onTransact()调用中。

如果两个或多个线程试图释放/删除相同的内存,则代码和设计都会被破坏。虽然线程同步原语会有所帮助,但我也不会使用它们。应该只有一个线程释放内存。理想情况下,它应该是分配内存的人。如果它不同,例如在跨线程消息传递的情况下,仍然只有一个目标线程应该删除内存。

这就像说一个线程打开一个文件,任何线程都会关闭它。看起来不太好。文件关闭应由单个线程完成,而不是由争用中的多个线程完成。

两件事:

1)free操作应该是原子的。因此,请使用任何机制,如互斥锁、信号量等。

2) 调用free()后,显式更新指向NULL的指针。所以在第二个线程中它不会屈服if()

请注意:free()调用后,不会将 NULL 分配给指针。

因为NULL free运行良好,什么都不做,所以使用它:

int *mem_ptr(NULL);
.
.
if(mem_ptr)
{
    //any multithreaded lock guard have to be here
    free(mem_ptr);
    mem_ptr = NULL;
}

因此,您唯一需要注意的是,操作free和设置指向NULL的指针必须是原子的。

这意味着

停止所有其他线程执行这些操作,直到一个线程未完成,这意味着使用核心同步对象。

您可以按照其他答案中的说明将指针分配给 NULL...但这仍然不能保证成功。两个线程可能一个接一个地通过并调用 free(),然后在此之后都分配给 NULL。但为时已晚,因为您的程序很可能已经崩溃。

您需要在此处使用线程同步机制,例如互斥锁:

std::mutex mtx;           // declare mutex for critical section
  :
  :
mtx.lock(); // only one thread will get inside here...
if(mem_ptr)
{
    //any multithreaded lock guard have to be here
    free(mem_ptr);
    mem_ptr = NULL;
}
mtx.unlock(); // release the mutex...