C++ Segfault,我不知道为什么

C++ Segfault and I dont know why?

本文关键字:为什么 我不知道 Segfault C++      更新时间:2023-10-16

我在头文件中声明了一个数组,如下所示:

private:
   int frames[10];

并在类构造函数中分配值,如下所示:

file.open(File);
if(file.is_open())
{
    std::string line;
    getline(file, line);
    std::string param[10];
    std::stringstream stream(line);
    int n=0;
    while(!stream.eof())
    {
        getline(stream, param[n], '$');
        frames[n] = atoi(param[n].c_str());
        n++;
    }
    file.close();
}

稍后在函数中使用此数组:

currentFrame++;
if(frames[currentAnimation] <= currentFrame)
{
    currentFrame = 0;
}

当我运行我运行我的代码时,我得到分段错误,gdb 返回以下内容:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000402c22 in Sprite::update (this=0x7ffff6efe678 <main_arena+88>) at Sprite.cpp:93 93              
if(frames[currentAnimation] <= currentFrame)
(gdb) bt
#0  0x0000000000402c22 in Sprite::update (this=0x7ffff6efe678 <main_arena+88>) at Sprite.cpp:93
#1  0x0000000000401fcb in main (argc=1, argv=0x7fffffffeb88) at main.cpp:146

不确定我哪里出错了,我认为错误就在这里的某个地方。我不能真正发布所有代码,因为它很多,但如果你需要更多具体信息请直接询问。

提前非常感谢你。

试试这个

private:
   std::vector<int> frames;

file.open(File);
if(file.is_open())
{
    std::string line;
    getline(file, line);
    std::string param;
    std::stringstream stream(line);
    while(getline(stream, param, '$'))
        frames.push_back(atoi(param.c_str()));
    file.close();
}
currentFrame++;
if( currentAnimation < frames.size() && frames[currentAnimation] <= currentFrame)
{
    currentFrame = 0;
}

查看洛基的答案,了解为什么while(!stream.eof())不好

写入

int n=0;
while(!stream.eof() && n < 10)
{

currentFrame++;
if(currentFrame < 10 && frames[currentAnimation] <= currentFrame)
{
    currentFrame = 0;
}

或使用类似的东西

currentFrame = (currentFrame + 1) % 10;

几个问题:

您这里只有 10 个项目:

std::string param[10];

但是这里没有检查 10:

while(!stream.eof())

因此,这可能会增加10多个,这肯定会引起问题。

此外,这种形式的循环几乎总是错误的:

while(!stream.eof())
{
    getline(stream, param[n], '$');
    frames[n] = atoi(param[n].c_str());
    n++;
}

如果您的输入中有任何错误数据,这将进入无限循环。否则,当您达到 EOF 时,std::getline()无法读取数据并设置 eof 标志,但您仍分配给帧(并递增 n)。 atoi()错误数据返回 0,因此Frames中的最后一个元素将为零(不确定这是否是预期行为(但它很草率)。

正确的样式是将读取置于 while 条件。因此,将这两件事加在一起,您的循环应该看起来像这样。

while(n < 10 && getline(stream, param[n], '$'))
{
    // loop is only entered if the read succeed.
    // Not sure about the type of `frames` so hard to talk about
    // if this loop is still correct. The meaning has changed slightly.
    frames[n] = atoi(param[n].c_str());
    n++;
}
if (n < 10) {/*We have an issue with not enough data!*/}