2012-10-17 26 views
5

Bir C++ programında garip bir segfault durumu ile karşı karşıya kaldım. Bunu küçük bir kodla çoğaltıyorum, ama neden olduğunu anlamıyorum.segfault

a.hpp: İşte kod

#pragma once 
#include <boost/shared_ptr.hpp> 
#include "b.hpp" 

class A 
{ 
    public: 
     explicit A();  
    private: 
     std::string str1_; 
     B b_; 
     std::string str2_; 
}; 

typedef boost::shared_ptr<A> A_ptr; 

a.cpp

#include "a.hpp" 
A::A() {} 

b.hpp

#pragma once 
#include <string> 

class B 
{ 
    public: 
     B(); 
    private: 
     std::string str1_; 
}; 

b.cpp

#include "b.hpp"  
B::B() {} 

main.cpp yapmak arasında

#include "a.hpp" 

int main() 
{ 
    A_ptr a(new A()); 
} 

Çıktı:

% make 
g++ -Wall -Wextra -g -fno-inline -O0 -c -o main.o main.cpp 
g++ -Wall -Wextra -g -fno-inline -O0 -c -o a.o a.cpp 
g++ -Wall -Wextra -g -fno-inline -O0 -c -o b.o b.cpp 
g++ -o main main.o a.o b.o 
dsymutil main 

Şimdi bu iyi çalışır.

% make 
g++ -Wall -Wextra -g -fno-inline -O0 -c -o a.o a.cpp 
g++ -o main main.o a.o b.o 
dsymutil main 

Ve şimdi programın çalışma sırasında parçalama arızası ile: Ben a.hpp dan B b_ (b_ beyanı) kaldırmak, a.cpp (bir yapı tetiklemek için) ve yeniden make çalıştırmak kurtarmak

(gdb) bt 
#0 0x00007fff97f106e5 in std::string::_Rep::_M_dispose() 
#1 0x00007fff97f10740 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() 
#2 0x0000000100001091 in A::~A (this=0x1001008b0) at a.hpp:8 
#3 0x00000001000011da in boost::checked_delete<A> (x=0x1001008b0) at checked_delete.hpp:34 
#4 0x0000000100001026 in boost::detail::sp_counted_impl_p<A>::dispose (this=0x1001008d0) at sp_counted_impl.hpp:78 
#5 0x0000000100000d9a in boost::detail::sp_counted_base::release (this=0x1001008d0) at sp_counted_base_gcc_x86.hpp:145 
#6 0x0000000100000dd4 in boost::detail::shared_count::~shared_count (this=0x7fff5fbff568) at shared_count.hpp:305 
#7 0x0000000100000f2b in boost::shared_ptr<A>::~shared_ptr (this=0x7fff5fbff560) at shared_ptr.hpp:159 
#8 0x0000000100000aac in main() at main.cpp:5 

Ve eğer make clean ve make daha sonra program segfault olmadan çalışır. Lütfen, sınıftan bir üyenin çıkarılmasının ve projenin temiz olmadan inşa edilmesinin neden program segfault olduğunu anlamama yardımcı olun. make sizin ikinci çalıştırmada

cevap

10

:

% make 
g++ -Wall -Wextra -g -fno-inline -O0 -c -o a.o a.cpp 
g++ -o main main.o a.o b.o 
dsymutil main 

sadece a.cpp recompiling edilmektedir. Ardından, make önceki işleminde üretilen nesne dosyalarının kalanına bağlanır. Bu, class A (a.o) için yeni nesne dosyasının daha yeni tanımı kullanacağından main.cppclass A (a.h içeriyor) eski tanımını kullanacaktır.

(Somut olarak, yeni class A'un farklı boyutu vardır, bu nedenle main() numaralı kutuda yığında saklanması gereken bellek farklıdır ve üye değişkenlerinin düzenlenmesi de farklıdır).

Bu, Makefile hesabınızda açıkça görülen hatalı bağımlılıklardan bir sorudur. Eğer make clean/make çalıştırdığınızda

, tüm dosyalar class A için aynı, doğru tanımı kullanacak ve her şeyi doğru bir şekilde çalışacaktır.

İlgili konular