c++ - 使用 Clang 而不是 GCC 构建(有问题的)示例时内存损坏

标签 c++ macos c++11 gcc boost

我有一些 C 代码,几年前被迅速“转换”为 C++ 代码,现在我正在维护。在不同的操作系统上运行它并使用不同的编译器构建时,我注意到一些奇怪的行为,并且可以使用一些帮助来诊断我最近解决的一些问题。


代码在以下系统上运行没有问题:

  • Ubuntu 14.04.2 LTS x64
  • 海湾合作委员会 4.8.4

将其移植到以下系统后,事情就变糟了:

  • OSX“El Capitan”
  • Apple LLVM 版本 7.3.0 (clang-703.0.29)

违规代码围绕以下结构展开:

struct blk_data {
    int i;
    int s;
    boost::mutex protectionMutex;
};

有一段代码,其中通过 malloc() 创建了此 POD 的动态实例(普通旧数据,无自定义方法或构造函数等):

struct blk_data* pData = (blk_data*)malloc(16 * sizeof(struct blk_data));
if ( pData )
//...

请忽略我正在转换 malloc() 的结果这一事实。如果我不这样做,编译器会标记错误。

稍后在代码中,我调用:

boost::unique_lock<boost::mutex> tempLock(pData->protectionMutex);

对于带有 GCC 的 Linux,没有问题。对于 OSX 和 Clang,程序会出错,指出最终传递给 pthread_mutex_lock() 的互斥锁地址无效。最终,我能够通过以下方式解决此问题:

  • 使用 new 代替 malloc()
  • 设置${CXXFLAGS} += -std=c++11

第二个会出现类似问题的情况是使用 new 的代码块,然后 memset 结构。据我了解,如果使用 POD struct,这是安全的。

为什么这段代码在 GCC/Linux 上构建和运行良好,但它构建了,但不运行;在 Clang/OSX 上?如果 struct 包含 RAII 样式的成员,它是否不再算作 POD struct,或者我是否一直违反了 C++ 标准的一部分(即:未定义的行为) ?或者这是在 Clang 与 GCC 中进行更严格检查的情况。

谢谢。

最佳答案

虽然我不确定 boost::mutex 是否是 POD,但是 malloc 只分配内存但不初始化对象,这使得 protectionMutex 未初始化。

new 确保调用 boost::mutex 的默认构造函数,从而初始化 protectionMutex

[更新] 检查 boost mutex 的 header file ,它在内部使用了一个指针:

#if defined(BOOST_HAS_WINTHREADS)
    typedef void* cv_state;
#elif defined(BOOST_HAS_PTHREADS)
    struct cv_state
    {
        pthread_mutex_t* pmutex;
    };
#elif defined(BOOST_HAS_MPTASKS)
    struct cv_state
    {
    };
#endif

所以malloc肯定不会初始化指针,而new会。

但我真的不知道为什么 GCC 可以工作...

关于c++ - 使用 Clang 而不是 GCC 构建(有问题的)示例时内存损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36746523/

相关文章:

C++ : Vector assignment error

macos - Docker nginx 容器 : http code 400

macos - 是否可以在 Mac 上使用特定于应用程序的 KeyBindings 覆盖用户 KeyBindings?

c++ - 避免调用默认、移动和复制构造函数

c++ - 在 typeid 检查有效后使用 reinterpret_cast 吗?

c++ - 如果从类(在单独的文件中)调用,SDL UpdateWindowSurface() 返回 -1

c++ - 将 Lab 值转换为 opencv 中的 RGB 值

objective-c - OSX/ cocoa : setting up service in menu for right click and services list

c++ - 有没有办法在c++中检测中文字符? (使用 boost )

c++ - llvm g++ 和 boost 函数