2012-06-21 42 views
4

我遇到錯誤sprintf語句。我添加了一個printf命令來幫助調查,並且似乎也許我的一個雙打沒有被理解(printf輸出一串無用數字,其中%3.1f應該是。)但是,第一次正確解釋double它在printf語句中被調用。通過將尺寸名稱從120增加到320,段錯誤確實消失。但是double仍然沒有被正確解釋,即它仍然輸出一串簡單的%3.1f應該是的無意義數字。我無法弄清楚我做錯了什麼。有任何想法嗎?代碼的最小測試用例版本和下面發佈的錯誤消息。錯誤sprintf語句使用雙(緩衝區溢出?)

#include <iostream> 
    #include <string> 
    #include <fstream> 
    #include <sstream> 
    #include <strstream> 
    #include <vector> 

    using namespace std; 


    void Back_Subt_beta() 
    { 

     int resonances = 4; 
     char name[320]; 
     double rpos[66]; 
     double rbinmin[66]; 
     double rbinmax[66]; 

     ifstream binedgein; 
     binedgein.open("binedges.dat"); 
     if (binedgein.is_open()) { 
      cout << "data file opens" << endl; 
      } 
     for (int vline=1; vline<=4; vline++) 
     { 
      binedgein >> var1 >> var2 >> var3; 
      rpos[vline-1] = var1; 
      rbinmin[vline-1] = var2; 
      rbinmax[vline-1] = var3; 
     } 
     binedgein.close(); 


     for (int m=2; m<=7; m++) 
     { 
      for (int j=0; j<resonances; j++) 
      { 
       printf("resonance%0#7.2feV/gammas_%3.1feV_Mcl%i", rpos[j],rpos[j],m); 
       sprintf(name,"resonance%0#7.2feV/gammas_%3.1feV_Mcl%i",rpos[j],rpos[j],m); 
      } 
     } 
     exit(); 
    } 

和binedges.dat

16.2  16.0  16.5 
38.75  38.25  39.25 
44.5  43.5  45.5 
55.25  54.75  55.75 

和錯誤文件:

Processing Back_Subt_beta.C... 
data file opens 

*** Break *** segmentation violation 
resonance0016.20eV/gammas_917241681885348612676436160464141677586357964289319457240620564649334534999701390133785258335880600276911524435084428436805391368574132924760441246552362332456319675531264.0eV_Mcl16(no debugging symbols found) 
Using host libthread_db library "/lib/tls/libthread_db.so.1". 
Attaching to program: /proc/7689/exe, process 7689 
[Thread debugging using libthread_db enabled] 
[New Thread -1208284352 (LWP 7689)] 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 
(no debugging symbols found)...done. 

0x006dd7a2 in _dl_sysinfo_int80() from /lib/ld-linux.so.2 
#1 0x014d3533 in __waitpid_nocancel() from /lib/tls/libc.so.6 
#2 0x0147c869 in do_system() from /lib/tls/libc.so.6 
#3 0x00962b8d in system() from /lib/tls/libpthread.so.0 
#4 0x00bebc8e in TUnixSystem::Exec() from /usr/local/root/lib/libCore.so 
#5 0x00be6dfb in TUnixSystem::StackTrace() from /usr/local/root/lib/libCore.so 
#6 0x00be5c53 in TUnixSystem::DispatchSignals() from /usr/local/root/lib/libCore.so 
#7 0x00bebf4d in SigHandler() from /usr/local/root/lib/libCore.so 
#8 0x00be0590 in sighandler() from /usr/local/root/lib/libCore.so 
#9 <signal handler called> 
#10 0x014b1d0a in strcmp() from /lib/tls/libc.so.6 
#11 0x003033be in G__searchvariable() from /usr/local/root/lib/libCint.so 
#12 0x002f9514 in G__getvariable() from /usr/local/root/lib/libCint.so 
#13 0x0021de97 in G__getitem() from /usr/local/root/lib/libCint.so 
#14 0xbfeb89dc in ??() 
#15 0x0021c633 in G__getexpr() from /usr/local/root/lib/libCint.so 
#16 0x00000048 in ??() 
#17 0x002e9bc8 in G__letvariable() from /usr/local/root/lib/libCint.so 
#18 0xbfeb987c in ??() 
Root > Function Back_Subt_beta() busy flag cleared 
+2

你確定問題不在於訪問無效的數組位置嗎? – 2012-06-21 19:58:04

+0

我不確定你的意思。但我用cout語句來確定段錯誤發生在sprintf行,而不是在我嘗試獲取sprintf命令中指定的文件後。所以我在之前插入了printf語句來查看sprintf在做什麼。 – neverskipbreakfast

+0

[Sprintf Segmentation Fault]的可能重複(http://stackoverflow.com/questions/7184227/sprintf-segmentation-fault) – 2012-06-21 20:21:37

回答

2

我覺得你的問題是,char陣列name只有120個字節,但你滿溢與您的sprintf聲明緩衝區。將您的char緩衝區的大小從120個字節增加到更大的值。更好的是,使用snprintf()而不是sprintf()

+0

將它增加到320,並且段錯誤停止,但sprintf的結果仍然是亂碼。我從來沒有使用過snprintf,但我現在會研究它... – neverskipbreakfast

+0

我想使用snprintf,但不幸的是我無法在我的系統上找到合適的頭文件(並且我不是管理員。 )我能夠通過將sprintf分成兩個不同的部分然後將它們組合來暫時解決問題。這很醜陋,但它是我立即可用的唯一工作解決方案。我會看看我能否爲將來找到這些頭文件。 – neverskipbreakfast

+0

@neverskipbreakfast:你有沒有嘗試'#include '。 – 2012-06-22 18:57:13

0

你正在溢出name字符數組,它只是120字符。更好的辦法是使用std::string namestr,然後做str.c_str()而餡name

1

我想知道這個數字是,所以我這樣做:

$ python 
Python 2.7.2+ (default, Oct 4 2011, 20:06:09) 
[GCC 4.6.1] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> x = 917241681885348612676436160464141677586357964289319457240620564649334534999701390133785258335880600276911524435084428436805391368574132924760441246552362332456319675531264.0 
>>> import struct 
>>> struct.pack('<d', x) 
'resonanc' 

所以原來的錯誤你的字符串覆蓋緩衝區肯定是造成。如果您獲得了不同的垃圾值,請嘗試查看實際位數,也許您會發現它。

+0

有趣!所以,即使當我增加char字符串的長度來命名[500]時,我仍然會得到相同的垃圾值,但是沒有segfault。 500可能不夠嗎?我不理解sprintf的侷限性嗎?也許有趣的是,我得到的最後一個變量也是不正確的。我應該得到像resonance0016.00eV/gammas_16.0eV_Mcl2這樣的東西,但是我會得到resonance0016.00eV/gammas_(垃圾)eV_Mcl16。 – neverskipbreakfast