क्लैंग 3.5.0 के साथ -फ्लो और साझा लाइब्रेरी से लिंक करते समय, ऐसा लगता है कि साझा लाइब्रेरी में operator delete
पर कॉल नहीं है मुख्य वस्तुओं से operator new
पर कॉल के रूप में एक ही प्रतीक संकल्प आदेश का पालन करें। उदाहरण:प्रतिस्थापित ऑपरेटर के साथ क्लैंग लिंक-टाइम ऑप्टिमाइज़ेशन नए कारणों से मेल नहीं खाता मुक्त()/valgrind
shared.cpp:
void deleteIt(int* ptr) {
delete ptr;
}
main.cpp:
$ clang++ -std=c++11 -g -O3 -flto -fuse-ld=gold -fPIC -shared shared.cpp -o libshared.so
$ clang++ -std=c++11 -g -O3 -flto -fuse-ld=gold main.cpp -L. -lshared -o main
$ LD_LIBRARY_PATH=. valgrind --quiet ./main
==20557== Mismatched free()/delete/delete []
==20557== at 0x4C2B6D0: operator delete(void*) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20557== by 0x4009F7: main (main.cpp:19)
==20557== Address 0x5a03040 is 0 bytes inside a block of size 4 alloc'd
==20557== at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==20557== by 0x4009EA: operator new (main.cpp:5)
==20557== by 0x4009EA: main (main.cpp:19)
==20557==
:
#include <cstdlib>
#include <new>
void* operator new(size_t size) {
void* result = std::malloc(size);
if (result == nullptr) {
throw std::bad_alloc();
}
return result;
}
void operator delete(void* ptr) noexcept {
std::free(ptr);
}
void deleteIt(int* ptr);
int main() {
deleteIt(new int);
return 0;
}
यहाँ जब मैं इसे बनाने और valgrind के माध्यम से इसे चलाने के क्या होता है
आप देख सकते हैं कि यह valgrind के operator delete
ढूंढ रहा है, लेकिन main.cpp
से उपयोग कर रहा है। इसके विपरीत, जीसीसी के साथ सटीक एक ही निर्माण (clang++
को g++
के साथ प्रतिस्थापित करें) ठीक काम करता है। कोई विचार क्यों, या इसके आसपास कैसे काम करना है?
संपादित करें: @Deduplicator द्वारा अनुरोध किए गए प्रतीक आयात और निर्यात।
$ objdump -T main | c++filt | grep operator
0000000000400990 g DF .text 0000000000000033 Base operator new(unsigned long)
0000000000000000 DF *UND* 0000000000000000 Base operator delete(void*)
$ objdump -T libshared.so | c++filt | grep operator
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4 operator delete(void*)
क्या आपने वास्तव में कोड के माध्यम से कदम रखा है (मुझे उम्मीद है कि साझा लाइब्रेरी की अपनी ढेर हो, इसलिए मैं पूरी तरह से आश्चर्यचकित नहीं हूं) –
मुझे लगता है कि मुख्य के लिए ऑपरेटर-डिलीट-लाइन समस्या को इंगित करती है। किसी कारण से, मुख्य हटाई जा रही निर्यात नहीं कर रहा है ... वास्तव में, हटाया गया था हटा दिया गया था। – Deduplicator
अच्छा पकड़ो। दिलचस्प बात यह है कि, यदि मैं 'ऑपरेटर डिलीट' के सी ++ 14 अधिभार को जोड़ता हूं और '-std = C++ 14' का उपयोग करता हूं, तो उसे निर्यात किया जाता है और सबकुछ काम करता है।लेकिन 'ऑपरेटर डिलीट (शून्य *) 'अभी भी निर्यात नहीं किया गया है। –