【问题标题】:How to fix 'Heap has been corrupted 'error in c++?如何修复 C++ 中的“堆已损坏”错误?
【发布时间】:2019-12-01 02:23:15
【问题描述】:

当我运行程序时,函数完成后出现异常“堆已损坏”

我已经读到,如果您使用已释放的内存,或者当您写入超出数组索引的索引时,可能会导致此异常。但没有一种情况适用于此。我已经阅读了一些问题的其他答案,但没有太大帮助。

`char fileNametoExport[26]="d:\\FOlder1\\part1.ipt";
 char WorkingFolderName[260] ="d:\\folder";
 int start = rFind(fileNametoExport, '\\');
 int finish = rFind(fileNametoExport, '.');
 if (start == -1)
 start = 0;
char partname[260];
strcpy(partname,substr(fileNametoExport, start, finish));
::AfxMessageBox((LPCTSTR)partname);
char xtfile[260];
char xmltxtfile[260];
strcpy(xtfile, strcat(WorkingFolderName, partname));
strcat(xtfile, "__Default.x_t");
strcpy(xmltxtfile, WorkingFolderName);
strcat(xmltxtfile,"_XT_SE_INV_Default_SOLID_0_Solid1_xt.xmt_txt");`

函数 rfind() 在 char 数组中查找 char 的出现-

int rFind(char* s, char c)
    {
    int sz = 0;
    char *tmp = s;
    while (*tmp != '\0')
    {
        sz++;
        tmp++;
    }
    for (int i = sz - 1; i >= 0; i--)
    {
        if (*(s + i) == c)
            return i;
    }
    return -1;
}

函数 substr() 获取从位置 x 到 y 的子字符串(不包含 y)

char* substr(char* s, const int b, const int f)
{
    char *str = new char[f - b];
    int t = 0;
    for (int i = b; i != f; i++)
    {
        str[t] = s[i];
        t++;
    }
    str[t] = '\0';
    return str;
}

P.S- 在提供输入时,我确保 fileNametoExport 始终包含“。”和 '\'。

【问题讨论】:

  • 那么是什么让你认为上面的代码是错误的原因?
  • 顺便说一下,你的代码有问题,你应该有 char fileNametoExport[26]="d:\\FOlder1\\part1.ipt";char WorkingFolderName[260] ="d:\\folder";。反斜杠必须在字符串文字中进行转义。
  • ::AfxMessageBox((LPCTSTR)partname); ~~这个消息框是否显示有效值?
  • @dorKKnight ,不,它不显示有效值。
  • @SonaliDBhavsar 顺便说一句,保护自己免受堆损坏问题的最佳方法是使用 C++ 功能,例如 std::stringstd::vector,而不是 C 字符串和数组。上面的代码是纯C。

标签: c++ arrays heap-memory heap-corruption


【解决方案1】:
  1. 您的程序不检查输入字符串的长度。您可以收到比缓冲区长的字符串,程序将失败。
  2. 如果你的程序得到 fileNametoExport = "d:\\somefolder\\somefilewithoutdot"finish 将是 -1 并且程序在 strcpy(partname,substr(fileNametoExport, start, finish)); 失败。
  3. 程序在char* substr(char* s, const int b, const int f)的缓冲区之后写入行

    str[t] = '\0';
    

    因为此时 t 等于 f-bstr 缓冲区的大小。

函数_ASSERTE( _CrtCheckMemory( ) ); 来自<crtdbg.h> 在搜索此类错误时非常有用。把它放在可疑代码周围,它会在你的错误之后失败。它仅在调试时有效。

【讨论】:

  • 我正在提供输入以确保文件名始终包含“。”和文件扩展名
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-05
  • 2017-09-12
  • 1970-01-01
  • 1970-01-01
  • 2021-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多