具有自定义new / delete和Qt的Segfault,在C ++中

问题描述 投票:3回答:1

所以我想稍微修改一下自定义的new / delete,然后按照this的答案进行操作。我有一个运行良好的MWE,但是一旦包含了Qt标头(即使不使用它),我得到的仅仅是分段错误。段错误在输入main()之前发生,我不知道发生了什么。这是代码:

/* main.cpp */
#include <iostream>
//#include <QString> // uncommenting this line causes the segfault

int main() {
    int* ref = new int(42);
    std::cout << ref << ", " << *ref << std::endl;
    delete ref;
}
/* custom_new.cpp */
#include <iostream>

void* operator new(size_t n) {
    void* result = malloc(n);
    std::cout << "Allocating " << n << " bytes at position " << result << std::endl;
    return result;
}

void operator delete(void* p) {
    std::cout << "Deleting memory at position " << p << std::endl;
    free(p);
}
# CMakeLists.txt
find_package(Qt5Core CONFIG REQUIRED)
add_library(custom_new custom_new.cpp)
add_executable(mwe main.cpp)
target_link_libraries(mwe Qt5::Core custom_new)

c++ qt new-operator
1个回答
0
投票

从全局cout内部访问operator new是个坏主意,因为cout可能尚未初始化。

libQt5Core有许多在main()之前运行的静态初始化程序,其中一些使用operator new分配内存。实际上,似乎QMutexcout之前被初始化,因此它在cout <<上崩溃。

$ gdb ./a.out
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x00007fffff22d426 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0  0x00007fffff22d426 in std::ostream::sentry::sentry(std::ostream&) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x00007fffff22da38 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2  0x00007fffff22de47 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00000000080013cd in operator new (n=32) at a.cpp:17
#4  0x00007fffff3658d2 in QMutex::QMutex(QMutex::RecursionMode) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#5  0x00007fffff47699f in qRegisterResourceData(int, unsigned char const*, unsigned char const*, unsigned char const*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#6  0x00007fffff34baa3 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#7  0x00007fffff7cf37a in call_init (l=<optimized out>, argc=argc@entry=1, argv=argv@entry=0x7ffffffee678, env=env@entry=0x7ffffffee688) at dl-init.c:72
#8  0x00007fffff7cf476 in call_init (env=0x7ffffffee688, argv=0x7ffffffee678, argc=1, l=<optimized out>) at dl-init.c:30
#9  _dl_init (main_map=0x7fffff7e9190, argc=1, argv=0x7ffffffee678, env=0x7ffffffee688) at dl-init.c:119
#10 0x00007fffff7c10ca in _dl_start_user () from /lib64/ld-linux-x86-64.so.2

如果您真的想在cout内使用operator new,请使用全局标记并将其设置为true内的main(),以便跳过main()之前的呼叫的输出。

© www.soinside.com 2019 - 2024. All rights reserved.