使用自定义 new/delete 和 C++ 中的 Qt 的段错误
Segfault with custom new/delete and Qt in C++
所以我想尝试一下自定义 new/delete 并按照 this 回答。我有一个运行良好的 MWE,但是一旦我包含 Qt header(即使不使用它),我得到的只是一个分段错误。段错误发生在输入 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)
从全局 operator new
内部访问 cout
是个坏主意,因为 cout
可能尚未初始化。
libQt5Core
在 main()
之前有许多 运行 的静态初始化器,其中一些使用 operator new
分配内存。事实上 QMutex
似乎在 cout
之前被初始化,所以它在 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
如果您真的想在 operator new
中使用 cout
,请使用全局标志并将其设置为 main()
中的 true
,以便跳过之前调用的输出main()
.
所以我想尝试一下自定义 new/delete 并按照 this 回答。我有一个运行良好的 MWE,但是一旦我包含 Qt header(即使不使用它),我得到的只是一个分段错误。段错误发生在输入 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)
从全局 operator new
内部访问 cout
是个坏主意,因为 cout
可能尚未初始化。
libQt5Core
在 main()
之前有许多 运行 的静态初始化器,其中一些使用 operator new
分配内存。事实上 QMutex
似乎在 cout
之前被初始化,所以它在 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
如果您真的想在 operator new
中使用 cout
,请使用全局标志并将其设置为 main()
中的 true
,以便跳过之前调用的输出main()
.