我正在尝试使用Arrays和C ++来演示一种难以检测的内存错误的方法。目的是激励STL向量的使用<>与迭代器结合使用。
编辑:接受的答案是我用来解释优缺点的答案。我还使用了:this
答案 0 :(得分:8)
不正确地配对新/删除和新[] /删除[]。
例如,使用:
int *array = new int[5];
delete array;
而不是:
int *array = new int[5];
delete [] array;
虽然c ++标准不允许,但有些编译器支持堆栈分配数组:
int stack_allocated_buffer[size_at_runtime];
这可能是作用域规则的意外副作用(例如,由成员变量隐藏的常量)......并且它会起作用,直到有人通过'size_at_runtime'太大并炸掉堆栈。然后是蹩脚的错误。
答案 1 :(得分:6)
内存泄漏? IMO,vector与迭代器结合使用并不能特别保护你免受错误的影响,比如超出界限或者通常使用无效的迭代器(除非你有VC ++和迭代器调试);相反它很方便,因为它为您实现了一个动态可调整大小的数组,并负责内存管理(NB!有助于使您的代码更加异常安全)。
void foo(const char* zzz)
{
int* arr = new int[size];
std::string s = zzz;
//...
delete[] arr;
}
如果发生异常(例如创建字符串时),则上面可能会泄漏。没有矢量。
Vector也因为它的值语义而更容易推理代码。
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 :(得分:4)
我认为std :: vector的实用程序确实显示了何时需要动态数组。
使用std :: vector创建一个示例。然后使用数组重新分配一个示例。我认为这说明了一切。
答案 3 :(得分:3)
一个显而易见的事实:
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
的定义方式。
答案 4 :(得分:3)
void Fn()
{
int *p = new int[256];
if ( p != NULL )
{
if ( !InitIntArray( p, 256 ) )
{
// Log error
return;
}
delete[] p;
}
}
你不会相信我经常看到这一点。任何形式的RAII都有用的典型例子......
答案 5 :(得分:3)
我认为使用vector
而不是动态数组的基本简单性已经令人信服。
vector<bool>
(谷歌说2003年,参见规范的23.2.4./1)。vector
而不是你的奇怪事情。使用动态数组,您需要自己跟踪大小,当您想要插入新元素时增长它,在不再需要时删除它...这是额外的工作。
哦,还有一个警告:vector<bool>
是一个肮脏的烂黑客和过早优化的经典例子。
答案 6 :(得分:2)
为什么不根据STL提供的算法来激励它?
答案 7 :(得分:0)
在原始数组中,operator [](如果我可以这样调用的话)容易受到索引越界问题的影响。使用矢量它不是(至少有一个运行时异常)。
抱歉,我没有仔细阅读这个问题。 index-out-of-bound是一个问题,但不是内存错误。