2010-11-19 13 views
2

Gerçekten bununla ne yapacağını bilmiyorum - bir dizeye bellek ayırırken programım çöküyor, çoğu zaman bu zararsız kodda 'ss < <' t atBir dize için bellek ayırırken SIGSEGV/SIGABRT alma

template <class T> 
inline string to_string (const T& t, bool use_fixed = false) 
{ 
    stringstream ss; 
    if (use_fixed) ss.setf(ios::fixed, ios::floatfield); 
    ss << t; 
    return ss.str(); 
} 

Özellikle kilitleniyor: bağlamlarda bir soruna neden olmamıştı. t tür int, == 0 idi. Böyle yığın izleme bakmak son hatları (ne yazık ki, ben bir ekran görüntüsü göndermek için çok yeniyim):

sahip olduğu Aklıma o şimdi benim programla farklı sadece muhtemelen alakalı bir şey olduğunu

0 ?? 
1 malloc 
2 operator new(unsigned int) 
3 std::string::_Rep::_S_create(unsigned int, unsigned int, std::allocator<char> const&) 
4 std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned int) 
5 std::string::reserve(unsigned int) 
6 std::basic_stringbuf<char, std::char_traits<char>, std:allocator<char> >::overflow(int) 
... 
o Birden fazla iş parçacığı ve birden çok iş parçacığı olan bir alt işlem başlatır ve bu işlevi de çağırır. Ubuntu 10.04'deyim. Teşekkür senin consideration--

Matt

+1

Tam bir yığın izi göndermeniz mümkün mü? Daha fazla bağlam olmadan neler olduğunu söylemek zor. Ayrıca, ilgili hatanın kendini gösterdiği kodla ilgisi olmaması da mümkündür. Tahminimce bir yerlerde dizi sınırlarının aşılması. Ne bulduğunuzu görmek için programınızı Valgrind veya DUMA'da çalıştırmayı deneyebilirsiniz. – Tristan

+0

Ne yazık ki, tam bir yığın izlemesi, benim => 10 olana kadar ve bir ekran görüntüsü yayınlayabildiğim zamana kadar mümkün değildir. :) Daha önce hiç valgrind kullanmamıştım, bunu göreceğim. –

+0

Neler olduğunu anladın mı? – highBandWidth

cevap

4

Böyle standart cevap için çöküyor yüzden bu yüzden, "nasılsa Bellek ayırıcı iç veri yapılarını yozlaştırdığını" dir. Dizi sınırlarınızı kontrol edin, çünkü bir bellek bloğu bağlarının dışına yazarsanız, yapmamanız gereken bir şeyin üzerine yazabilirsiniz.

+1

Sağ. Ama bunu nasıl yapabilirim? Bunun sadece dizelerle (to_string olmasa bile) gerçekleştiği bir örnek geçersizdir MyClass :: Member {string str; ... str = "işte bir dizi"; } atamada bir kilitlenme ile. str yereldir, hiçbir şeyi gölgede bırakmaz. –

+0

Oldukça basit: char * p = new char [2]; p [2] = 'c'; Olmaması gereken yere yazıyor. –

+1

std :: string kullanıyorum char * değil. STL tüm tahsisini yapıyor. Öyleyse STL'i nasıl mahvedebilirim? –

2

Aslında Matias Valdenegro size doğru cevabı verdi. Ancak, bunu bir şekilde yaptı, bunu anlamadınız: Hafıza ayrıştırıcısının iç veri yapılarını bir şekilde bozduğunuzu söyledi. Ve tam olarak ne yapıyordun. sizin için tek anlamadı (ve Matias sana söylemedi): Burada alıntı yaptığınız kodda öbür bozucu olmuyorsunuz. Yığını başka yerde bozuyorsunuz. Belirtilen kod sadece iptal sinyalini tetikler, çünkü allocator fonksiyonlarının (yani yeni operatör) 'un tespit ettiği nokta, yığının bozulmasına neden olur (başka bir yerde). Ve işte bu yüzden - yorumunuzun tam tersi - C++ 'ler std :: to_string burada hiçbir işe yaramayacaktır (eğer yığının bozulmasına yol açarsa SIGABRT da olacaktır) ve bir şey üzerinde çalışıyorken hatanın aniden ortadan kalkmasıdır. başka bir yerde. Açıkçası, sadece ilk başta yığın bozulmasına neden olan hatayı düzelttiniz.

Bu tür bir hatayı bulmak için harika bir araç valgrind olarak adlandırılır, eğer henüz bilmiyorsanız, bunu kesinlikle değiştirmelisiniz çünkü size sadece neler olduğunu anlatamazdım, aynı zamanda gerçek hata bulunur.

İlgili konular