【问题标题】:buffer overrun when loading from a previous saved file从以前保存的文件加载时缓冲区溢出
【发布时间】:2012-02-08 07:05:24
【问题描述】:

我做了一个带有加载/保存选项的文字冒险。 在我创建游戏的文件夹中,它运行良好。即使我制作了我的游戏的发布版本,它也能正常运行。

但我必须把这个项目交给我的教授。 在我的 PC 上,保存和加载工作正常,但在我的笔记本电脑或我的项目文件夹的副本上,我收到错误消息“缓冲区溢出已累积”。 那我的错在哪里?

我要加载/保存的代码:

bool save()
{
    char sFileText[1024];
    char sFileName[80];
    char sFileDirectory[80];

     GetCurrentDirectory(512, sFileDirectory); 

    sprintf(sFileName, "%s\\save_game.ini", sFileDirectory);

    sprintf(sFileText, "[settings]\n\rsp_loop=%i\n\rroom_iSelect=%i\n\riSelect=%i\n\rraum=%i\n\rtor402=%i\n\rwegiSelect=%i\n\rwegweiser=%i\n\rlight=%i\n\ropen_door=%i\n\rmesser=%i\n\rmesserwurf=%i\n\rkamera=%i\n\rstein=%i\n\ralive=%i\n\rpfeil=%i\n\rluke=%i\n\rkuehlschrank=%i\n\rpulver_schmand=%i\n\rteddy=%i\n\rseil=%i\n\rgiftklinge=%i\n\r",
         sp_loop,
         room_iSelect,
         iSelect,
         raum,
         tor402,
         wegiSelect,
         wegweiser,
         light,
         open_door,
         messer,
         messerwurf,
         kamera,
         stein,
         alive,
         pfeil,
         luke,
         kuehlschrank,
         pulver_schmand,
         teddy,
         seil,
         giftklinge
        );


    int cur_char;
    FILE *out_file;

    out_file = fopen(sFileName, "w");
    if (!out_file == NULL) 
    {
        for (cur_char = 0; cur_char < strlen(sFileText); ++cur_char) 
        {
            fputc(sFileText[cur_char], out_file);
        }
    }
    else
    {
        return false;
    }

    fclose(out_file);
    return true;
}

bool open()
{
    char sFileText[1024];
    char sFileName[12];
    char sFileGameSettingsIni[80];

    sprintf(sFileName, "save_game.ini");



    GetCurrentDirectory(512, sFileGameSettingsIni); 

    sprintf(sFileGameSettingsIni, "%s\\%s", sFileGameSettingsIni, sFileName);

    sp_loop = GetPrivateProfileInt("settings", "sp_loop", 512, sFileGameSettingsIni);

    raum = GetPrivateProfileInt("settings", "raum", 512, sFileGameSettingsIni);
    tor402 = GetPrivateProfileInt("settings", "tor402",512, sFileGameSettingsIni);
    wegiSelect = GetPrivateProfileInt("settings", "wegiSelect", 512, sFileGameSettingsIni);
    wegweiser = GetPrivateProfileInt("settings", "wegweiser", 512, sFileGameSettingsIni);
    light = GetPrivateProfileInt("settings", "light", 512, sFileGameSettingsIni);
    open_door = GetPrivateProfileInt("settings", "open_door",512, sFileGameSettingsIni);
    messer = GetPrivateProfileInt("settings", "messer", 512, sFileGameSettingsIni);
    messerwurf = GetPrivateProfileInt("settings", "messerwurf", 512, sFileGameSettingsIni);
    kamera = GetPrivateProfileInt("settings", "kamera", 512, sFileGameSettingsIni);
    stein = GetPrivateProfileInt("settings", "stein", 512,sFileGameSettingsIni);
    alive = GetPrivateProfileInt("settings", "alive", 512,sFileGameSettingsIni);
    pfeil = GetPrivateProfileInt("settings", "pfeil", 512, sFileGameSettingsIni);
    luke = GetPrivateProfileInt("settings", "luke", 512,  sFileGameSettingsIni);
    kuehlschrank = GetPrivateProfileInt("settings", "kuehlschrank", 512, sFileGameSettingsIni);
    pulver_schmand = GetPrivateProfileInt("settings", "pulver_schmand", 512, sFileGameSettingsIni);
    teddy = GetPrivateProfileInt("settings", "teddy", 512, sFileGameSettingsIni);
    seil = GetPrivateProfileInt("settings", "seil", 512, sFileGameSettingsIni);
    giftklinge = GetPrivateProfileInt("settings", "giftklinge",512, sFileGameSettingsIni);

    return true;
}

【问题讨论】:

  • 我认为应该标记为 C 而不是 c++。可能还需要更多代码。

标签: c load save ini


【解决方案1】:

一个可能的原因是GetCurrentDirectory的错误使用:

char sFileDirectory[80];

GetCurrentDirectory(512, sFileDirectory);

这表示sFileDirectory 最多可容纳 512 个字符:它最多只能容纳 80 个字符(包括 NULL 终止符),因此这很容易超出 sFileDirectory 的结尾。

改为:

GetCurrentDirectory(sizeof(sFileDirectory) - 1, sFileDirectory); /* Check the return value. */

由于当前目录较短,它可能在您的 PC 上工作,而在另一台 PC 上,它可能存储在路径大于 79 个字符的目录中。

另一个问题是:

char sFileName[12];

sprintf(sFileName, "save_game.ini");

“save_game.ini”的长度为 13 个字符。 改为:

char sFileName[14];

sprintf(sFileName, "save_game.ini");

或:

const char* sFileName = "save_game.ini";

还可以考虑使用_snprintf 而不是sprintf

【讨论】:

    【解决方案2】:

    您将sFileName 定义为sFileName[12],然后尝试向其写入14 个字节(13 个和一个NULL)。看起来您传递给GetCurrentDirectory() 的缓冲区还不够大。您说缓冲区的长度为 512 字节,而您仅将其定义为 80 个字符宽。

    GetCurrentDirectory() 的返回值将告诉您缓冲区需要多大。

    【讨论】:

      【解决方案3】:

      sFileDirectory 与 GetCurrentDirectory 的缓冲区大小相比非常小。尝试放大以适应相同的尺寸。在发布机器上可能会有所不同。

      【讨论】:

      • 我找到了一个非常简单的解决方案...而不是写 sFileName[12];我写了 sFileName[] = "save_game.ini";现在这工作正常!谢谢大家!
      猜你喜欢
      • 1970-01-01
      • 2013-01-10
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 2016-09-19
      • 2017-05-13
      相关资源
      最近更新 更多