【问题标题】:Why is this code throwing an exception when using dynamic memory allocation?为什么在使用动态内存分配时这段代码会抛出异常?
【发布时间】:2020-03-19 00:17:35
【问题描述】:

下面的程序创建一个新的结构数组[n+5]元素,每次数量达到51015,...并将旧元素复制到一个新数组中。

这是抛出的错误:

在 ConsoleApplication4.exe 中的 0x7AE740DF (vcruntime140d.dll) 处引发异常:0xC0000005:访问冲突写入位置 0x6CBFEBB8。

错误在第 69 行抛出,其中显示 items += 1;

#include <iostream>
#include <iomanip>

using namespace std;

struct item{
    string name;
    int eff;
};

item* ptr = nullptr;
item* temp = nullptr;
int itemsA = 0;
int arrSize = 5;
int lastElement = 0;


void func(int&, item *& ,int&, int& , item*&);

int main()
{
    ptr = new item[arrSize];

    func(arrSize, ptr,itemsA,lastElement, temp);


}
void func(int& arrSize, item *& ptr, int &items, int&lastElement, item *& temp)
{
    bool event = false;
    int a = 1;
    while (a == 1)
    {
        cout << "Your array size is: " << arrSize << endl;
        if (items > arrSize)
        {
            temp = new item[arrSize];

            for (int x = 0; x < arrSize; x++)
            {
                temp[x].eff = ptr[x].eff;
                temp[x].name = ptr[x].name;
            }
            arrSize += 5;
            delete[] ptr;
            ptr = nullptr;
            ptr = new item[arrSize];

            for (int x = 0; x < arrSize; x++)
            {
                ptr[x].name = temp[x].name;
                ptr[x].eff = temp[x].eff;
            }
            delete[] temp;
            temp = nullptr;

        }
        int any;
        string any2;
        cout << "ENter name for position number: " << lastElement + 1 << "\n";
        cin >> any2;
        cout << "ENter int for hp effect for position number: " << lastElement + 1 << "\n";
        cin >> any;
        ptr[lastElement].eff = any;
        ptr[lastElement].name = any2;
        items +=1;                                //////////the error is thrown here
        cout << "You now have " << items << " items.\n";


        cout << "Items in your bag: \n";
        for (int x = 0; x < items; x++)
        {
            cout << ptr[x].name << " which gives you extra " << ptr[x].eff << " health when used.\n";
        }
        lastElement += 1;

    }
}

【问题讨论】:

  • func() 中的第二个for 循环访问temp 末尾的元素。您随后的代码不会检查lastElement 是否是ptr 的有效索引,而是将其用作索引。访问数组的无效索引(是否动态分配)不会神奇地调整该数组的大小 - 它只会导致未定义的行为。
  • 无关:为了能够分析编程问题,请尽量使程序的每一小部分都清晰。一个函数应该有一个函数/目的。如果函数的描述性名称需要比执行该函数的代码长,请将函数分成几部分。如果你想出一个像a_function_that_first_does_this_and_then_this_but_only_if_that 这样的函数的名字,那肯定是你应该拆分它的信号。您的 main(通过调用 void func(int&amp;, item *&amp; ,int&amp;, int&amp; , item*&amp;); 代理)看起来有一些。
  • @Peter,感谢您提供有关 for 循环的提示。一旦我解决了这个问题,代码就会按预期工作。至于 int lastElement 用作索引,这是我对如何访问数组中最后一个空元素的想法。当然,这可能是错误的,因为我是编码新手,但是从您的回答中,我不太明白为什么会出现问题。无论如何,遵循您的第一个提示对我帮助很大,所以我想再次感谢您。
  • @TedLyngmo 谢谢你的提示!我的代码现在看起来好多了
  • @MichaelMichael - 我不太清楚你的意思。如果一个数组有(比如说)两个元素,那么访问第三个元素会给出未定义的行为。识别数组的最后一个元素并不是一种神奇的方法。

标签: c++ pointers exception memory dynamic


【解决方案1】:

您正在越界访问数组。当items == arrSize 时,您尝试写入ptr[lastElement],因为lastElementitems 将具有相同的值,所以将写入超过分配空间末尾的ptr[arrSize]

您的数组扩展代码中也存在许多问题,并且您正在传递不需要的参数。

【讨论】:

  • 谢谢!它帮助我修复了代码!至于你的第二句话,哪些参数是不需要的?
  • @MichaelMichael 您将变量传递给 func,而这些变量应该是本地变量(例如 temp)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多