使用double的sprintf语句出错(缓冲区溢出?)

时间:2012-06-21 19:52:21

标签: c++ arrays segmentation-fault printf

我遇到错误的sprintf语句。我添加了一个printf命令来帮助调查,似乎我的双打之一可能没有被理解(printf输出一串无意义的数字,其中%3.1f应该是。)但是,double是第一次被正确解释它在printf语句中调用。通过将大小名称从120增加到320,segfault确实消失了。但双重仍然没有被正确解释,即它仍然输出一串无意义的数字,其中一个简单的%3.1f应该是。我无法弄清楚我做错了什么。有任何想法吗?代码的最小测试用例版本和下面发布的错误消息。

    #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

3 个答案:

答案 0 :(得分:2)

我认为您的问题是char数组name只有120个字节,但是您使用sprintf语句溢出了该缓冲区。将char缓冲区的大小从120字节增加到更大的值。更好的是,使用snprintf()代替sprintf()

答案 1 :(得分: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'

因此原始错误肯定是由您的字符串覆盖缓冲区引起的。如果您获得了不同的垃圾值,请尝试查看实际位,也许您会想出来。

答案 2 :(得分:0)

你溢出name char数组,只有120个字符。更好的方法是使用std::string namestr,然后在填充str.c_str()

时执行name