std :: allocator <t>:是否允许在C ++中构建未分配的内存?

时间:2018-05-22 10:06:40

标签: c++ allocator

所以我对C ++比较陌生,最近我遇到了std::allocator类。我了解这是一个用于创建vectorlistdeque等的强大工具,我正在努力了解它。 令我困惑的一件事是:

例如,如果我们定义一些allocator<int>表示为alloc,我们会通过n使用它在内存中分配auto const b = a.allocate(n)个位置,其中b是指向已分配内存中第一个int元素的指针,然后,还有一个人必须构造分配的内存才能实际访问它,对吗? 如果我们引入一些迭代指针auto e=b,则可以通过alloc.construct(e++,int_obj)执行构造,其中int_objint类型的一些用户初始化对象。只要construct的总呼叫数小于n,这一切都很好并且温顺。但是,我不太确定当construct的用户来电次数超过n时会发生什么。我最初预计会发出一些警告或错误信息来支持它丑陋的头脑,但是没有任何反应。举个简单的例子,这里是我试图运行的代码:

int n{ 0 };                            // Size of the array is initialized to 0.
cin >> n;                              // User reads in the size.
allocator<int> alloc;                  // 'alloc' is an object that can allocate ints.
auto const b = alloc.allocate(n);      // Pointer to the beginning of the array. 
auto e = b;                            // Moving iterator that will point to the end of the array

for (int i = 0;i != 10;++i)
    alloc.construct(e++, i);           // We start constructing 10 elements in the array, regardless of the size n, which can in principle be less than 10.
for (auto i = b;i != e;++i)
    cout << *i << "\t";

最初我为n=1运行此代码,一切正常;它打印出从0到9的数字,即使我只为一个数字分配空间。那已经是一面红旗吧?然后我将n更改为2,并在打印第四位数后打破程序,这更符合我的预期。

我从这种行为中得出的结论是,尝试通过std::allocator构造尚未分配的内存是未定义和不可预测的,因此应该避免(这一点很明显)。但是,这似乎是非常危险的陷阱,我想知道C ++中是否存在一些内置的解决方法,它们在尝试构建未分配的内存时总是会阻止用户。

1 个答案:

答案 0 :(得分:2)

  

但是,这似乎是一个非常危险的陷阱,

当然是,你有责任避免这个陷阱。这就是为什么总是建议首先使用现有容器,因为它们经过仔细编写,审核和测试以避免此类错误。

如果您确实需要直接处理原始内存,通常最好编写自己的容器,您可以将其测试到类似的标准,而不是将手动内存管理与其他程序逻辑交错。

  

我想知道C ++中是否有一些内置的解决方法,在尝试构建未分配的内存时总会阻止用户

不,因为在写入时不一定会导致运行时成本不正确。我不希望我的程序运行得更慢,因为其他人对他们的工作不好。

但是,有很多工具可以帮助您测试和诊断这些错误,例如:

  • clang和gcc编译器有地址清理程序,可以将这些检查编译到你的程序中(它是一个可选的编译工具而不是语言的一部分)
  • valgrind是一个外部程序,其默认工具(memcheck)运行您的真实程序来查找这些错误。它很慢,但它用于测试或调试,而不是用于实时节目