运行时间检查:变量周围的堆栈已损坏

Run-time check: stack around variable was corrupted

本文关键字:堆栈 已损坏 周围 变量 检查 运行时间      更新时间:2023-10-16

我正在创建一个程序,该程序将重写来自文件的值的数组。我已经链接了下面的代码。运行文件时,我会收到错误"运行时检查失败,堆叠'arr'变量已损坏。

另外,程序的输出以相同的数字返回所有数组位置,

arr[0] = -858993460

文件中的数字是:
12
13
15

#include<iostream>;
#include<fstream>;
using namespace std;
template <class T>
void init(T * a, int size, T v)//done
{
    for (int i = 0; i < size; i++)
    {
        a[size] = v;
    }
}
bool getNumbers(char * file, int * a, int & size)//not done
{
    int count = 0;
    ifstream f(file);
    while (f.good() == true && count < 1)
    {
        f >> a[count];
        count++;
    }
    if (size > count)
    {
        return true;
    }
    else if (size < count)
    {
        return false;
    }
}
void testGetNumbers()
{
    int arr[5];
    int size = 5;
    cout << "Testing init and getNumbers." << endl;
    init(arr, 5, -1);
    cout << "Before getNumbers: " << endl;
    for (int i = 0; i < size; i++)
    {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }
    if (getNumbers("nums.txt", arr, size))
    {
        cout << size << " numbers read from file" << endl;
    }
    else
    {
        cout << "Array not large enough" << endl;
    }
    cout << "After getNumbers: " << endl;
    for (int i = 0; i < size; i++)
    {
        cout << "arr[" << i << "] = " << arr[i] << endl;
    }
    cout << endl;
}
int main()
{
    testGetNumbers();
    return 0;
}

第一个循环中的这一行看起来就像有错误。

a[size] = v;

它导致数组绑定的访问和内存/堆栈损坏。应该是

a[i] = v;

main函数开始,行

return 0;

...不是必需的,因为这是main的默认返回值。我会删除它,有些人坚持要拥有它,我认为大多数人都不在乎。但是,最好完全意识到代码的隐式或明确表示什么,因此:返回0表示程序成功。。

对于明确的main返回值,我建议使用<stdlib.h>标头的名称EXIT_SUCCESSEXIT_FAILURE

那么更清楚。


main调用 testGetNumbers,除了输出语句外,它以这样的启动:

int arr[5];
int size = 5;
init(arr, 5, -1);

碰巧的是,init功能具有未定义的行为不会按预期填充-1值,但无视。现在,只看上面的详细性。考虑写这篇文章:

vector<int> arr( 5, -1 );

使用<vector>标头的std::vector


呼叫链条向下进入init,发现

a[size] = v;

试图将值v分配给数组末尾的项目。

具有未定义的行为

可能应该是

a[i] = v;

,但如前所述,当您使用std::vector时,整个功能是多余的,除非您的老师严格禁止。


testGetNumbers中备份,它继续致电getNumbers,在该功能中,我们找到

ifstream f(file);
while (f.good() == true && count < 1)
{
    f >> a[count];
    count++;
}

通常,永远不要在循环条件下使用f.good()f.eof():使用f.fail()。另外,〜切勿将布尔值与truefalse进行比较,只需直接使用它即可。然后循环看起来像这样:

ifstream f(file);
while (!f.fail() && count < 1)
{
    f >> a[count];
    count++;
}

提示:在标准C 中,您可以将!编写为not&&作为and。使用Visual C 编译器,您必须包括<iso646.h>标头才能做到这一点。

免责声明:这里指出的修复程序不能保证循环为您的预期目的正确。实际上,当输入操作失败时,count的增量也可能是意想不到的。循环极限的同上。


继续(或更确切地说,结束(函数
if (size > count)
{
    return true;
}
else if (size < count)
{
    return false;
}

这有一个很大的问题:如果size == count怎么办?然后,执行将继续从函数的末尾删除而不会返回值。这再次是未定义的行为

我留给您决定要在这种情况下返回的功能,并确保这样做。

在您的init功能中...

template <class T>
void init(T * a, int size, T v)//done
{
    for (int i = 0; i < size; i++)
    {
        a[size] = v;
    }
}

nope:

a[size] = v;

是:

a[i] = v;