代码之家  ›  专栏  ›  技术社区  ›  Sebastian

如何在C++中使用数组演示内存错误

  •  6
  • Sebastian  · 技术社区  · 14 年前

    我试图想出一种方法来演示一种使用数组和C++的内存错误,这是很难检测到的。目的是激发STL向量与迭代器的结合使用。

    编辑: 公认的答案是我用来解释优点/缺点的答案。我也用过: this

    8 回复  |  直到 14 年前
        1
  •  6
  •   UncleBens    14 年前

    内存泄漏?imo,vector与迭代器结合使用并不能特别保护您不受错误的影响,例如越界或通常使用无效的迭代器(除非您有带迭代器调试的VC++);相反,它很方便,因为它为您实现了一个动态可调整大小的数组并负责内存管理(nb!有助于提高代码的异常安全性)。

    void foo(const char* zzz)
    {
        int* arr = new int[size];
        std::string s = zzz;
        //...
        delete[] arr;
    }
    

    如果发生异常(例如创建字符串时),上面的内容可能会泄漏。没有向量。

    由于向量的值语义,它也使得对代码进行推理变得更加容易。

    int* arr = new int[size];
    int* second_ref = arr;
    //...
    delete [] arr; 
    arr = 0; //play it safe :)
    
    //...
    second_ref[x] = y;
    //...
    delete [] second_ref;
    

    但向量可能不能自动满足100%的动态数组用例。(例如,还有 boost::shared_array 和将要 std::unique_ptr<T[]> )

        2
  •  8
  •   Stephen    14 年前

    新建/删除和新建[]/删除[]的配对不正确。

    例如,使用:

    int *array = new int[5];
    delete array;
    

    而不是:

    int *array = new int[5];
    delete [] array;
    

    虽然C++标准不允许它,但有些编译器支持堆栈分配数组:

    int stack_allocated_buffer[size_at_runtime];
    

    这可能是作用域规则的意外副作用(例如,常量被成员变量隐藏)。它一直工作,直到有人在运行时通过了“大小”太大,并吹出堆栈。接着就出现了一些蹩脚的错误。

        3
  •  4
  •   Nikko    14 年前

    我认为std::vector的实用程序在需要动态数组时会真正显示出来。

    用std::vector做一个例子。然后一个使用数组重新分配的示例。我认为这说明了它自己。

        4
  •  3
  •   David Thornley    14 年前

    一个明显的现象是:

    for (i = 0; i < NUMBER_OF_ELEMENTS; ++i)
        destination_array[i] = whatever(i);
    

    对战

    for (i = 0; i < NUMBER_OF_ELEMENTS; ++i)
        destination_vector.push_back(whatever(i));
    

    指出你知道第二种方法有效,但第一种方法是否有效取决于 destination_array 定义。

        5
  •  3
  •   Goz    14 年前
    void Fn()
    {
        int *p = new int[256];
        if ( p != NULL )
        {
            if ( !InitIntArray( p, 256 ) )
            {
                  // Log error
                  return;
            }
            delete[] p;
        }
    }
    

    你不会相信我多久见一次。一个典型的例子,任何形式的RAII都是有用的…

        6
  •  3
  •   Matteo Italia    14 年前

    我认为使用的基本简单性 vector 而不是动态数组已经令人信服了。

    1. 你不必记住删除你的内存……这并不是那么简单,因为删除内存的尝试可能会被异常和其他事情绕过。
    2. 如果你想自己做动态数组,C++中最安全的方法是将它们包在一个类中并使用。 RAII . 但是向量帮你做到了。事实上,这就是重点。
    3. 调整大小是为您完成的。
    4. 如果你需要支持任意类型,你不需要做任何额外的工作。
    5. 提供了大量的算法来处理容器,包括其他用户和其他用户。
    6. 如果需要,您仍然可以通过传递向量的基础数组来使用需要数组的函数;标准保证内存是连续的,除了 vector<bool> (谷歌称,截至2003年,见规范23.2.4./1)。
    7. 一般来说,自己使用数组可能是不好的做法,因为 re-inventing the wheel …而且您的实现几乎肯定会比现有的更糟糕……而且对其他人来说更难使用,因为他们知道 矢量 但不是你的怪事。

    使用动态数组,您需要自己跟踪大小,在插入新元素时增大大小,在不再需要时删除大小…这是额外的工作。 哦,还有一个警告: 矢量<bool> 是一个肮脏的腐烂的黑客和一个典型的过早优化的例子。

        7
  •  2
  •   Ken Bloom    14 年前

    你为什么不根据STL提供的算法来激励它呢?

        8
  •  0
  •   Arun    14 年前

    在原始数组中,运算符[](如果我可以调用它)易受索引越界问题的影响。对于向量,它不是(至少有一个运行时异常)。

    对不起,我没有仔细阅读这个问题。索引超出限制是一个问题,但不是内存错误。