【问题标题】:dynamic memory allocation c++动态内存分配 C++
【发布时间】:2015-04-27 20:59:52
【问题描述】:

我有以下动态分配的数组

int capacity = 0;
int *myarr = new int [capacity];

如果我这样做会发生什么:

for (int i = 0; i < 5; ++i) 
myarr[++capacity] = 1;

如果for 循环的执行次数超过 5 次,这会导致错误吗?它适用于小数字,但我想知道这是否可能是一种错误的方法。

【问题讨论】:

  • 欢迎来到未定义行为的土地
  • 这无论如何都会导致错误。您已经创建了一个大小为 0 的数组,您放入数组中的任何内容实际上都放在了数组之后。
  • “它工作得很好” - 不,它没有,它只是看起来那样。
  • 对于所有可能的情况,这绝对是错误的方法。
  • 您看到错误的事实意味着您犯了错误。您没有看到错误的事实并不意味着您没有犯错误。您正在调用未定义的行为并且您知道它(您正在写入未分配的内存区域):目的是什么?

标签: c++ memory dynamic allocation


【解决方案1】:

您正在设置超出数组边界的内存。这可能会覆盖程序另一部分正在使用的内存,这是未定义的行为。要解决这个问题,你应该像这样声明你的数组:

int* myArray = new int[5];

这样你就不会分配超出数组的范围。

但是,最好使用std::vector。它将通过管理内存本身来防止此类情况的发生。您可以像这样向std::vector 添加项目:

Vector.push_back(myItem);

你可以像这样声明一个整数向量:

std::vector<int> Vector;

你可以阅读更多关于std::vectorhere的信息。

【讨论】:

    【解决方案2】:

    这将导致越界访问。这只是未定义的行为。您的程序可能会崩溃,您的汽车可能无法在早上启动,您可以在这里看到模式。

    在您的情况下它恰好工作正常,因为通常操作系统分配的比您要求的多,通常是 2 的倍数,所以可能在这里它至少分配 8/16..256 字节。但是你不应该依赖这种行为。

    编辑汽车问题(几乎)是个笑话,但未定义的行为实际上意味着未定义。 C++ 标准决定不对许多此类问题强制执行编译器检查,因为检查需要时间。因此它将行为声明为未定义行为 (UB)。在这种情况下,绝对没有任何保证。如果你工作,例如在一些控制飞机方向舵的小型嵌入式系统上,你可以猜到会发生什么。

    【讨论】:

      【解决方案3】:

      这种方法在 c++ 中是错误的。使用 new 分配内存为新的“容量”对象分配内存,您可以访问这些对象而不会在运行时错误中运行。 这是在 c++ 中管理原始数组的更好方法:

      int capacity = 10;
      int *myarr = new int [capacity];
      
      for (int i = 0; i < 20 ; ++i) {
        if (capacity < i) {
          // allocate more memory and copy the old data
          int *old_data = myarr;
          myarr = new int [capacity * 2]
          for (int j = 0; j < capacity; ++j) {
            myarr[j] = old_data[j];
            capacity *= 2;
          }
          delete [] old_data;
        }
        myarr[i] = 1;
      }
      

      最后最好打电话给delete []。在 c++ 中使用预制动态数组的另一种方法是使用 std:array(在 c++11 中支持)或 std::vector(或旧版支持和我的首选选项)库,它会自动重新分配更多内存。 更多关于向量和数组的信息以及这里的向量示例here 和here 对于 std::array。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-07
        • 2015-06-27
        • 2021-02-28
        • 2012-01-20
        • 2015-09-25
        • 2018-01-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多