std::allocator<T>: 是否允许在 C++ 中构建未分配的内存?
std::allocator<T>: Is constructing on unallocated memory in C++ allowed?
所以我对C++比较陌生,最近遇到了std::allocator
class。我知道这是用于创建 vector
s、list
s、deque
s 等的强大工具,我正在尝试了解更多相关信息。
让我感到困惑的一件事如下:
例如,如果我们定义一些 allocator<int>
表示为 alloc
,我们使用它通过 auto const b = a.allocate(n)
在内存中分配 n
个位置,其中 b
是指向分配内存中第一个 int
元素的指针,那么,为了实际访问它,也有义务构造分配内存,对吧?
如果我们引入一些迭代指针 auto e=b
,那么可以通过 alloc.construct(e++,int_obj)
执行构造,其中 int_obj
是类型 int
的某个用户初始化对象。只要对 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 的数字,即使我只为一个数字分配了 space。那已经是危险信号了,对吧?然后我将 n
更改为 2
,程序在打印数字四后中断,这更符合我的预期。
我从这种行为中得出的结论是,尝试通过 std::allocator
构建尚未分配的内存是未定义和不可预测的,因此应该避免(一开始就很明显)。但是,这似乎是一个极其危险的陷阱,我想知道 C++ 中是否有一些内置的解决方法,在尝试构造未分配的内存时总是会阻止用户。
But, this seems as as extremely dangerous pitfall,
这当然是,您有责任避免这种陷阱。这就是为什么始终建议首先使用现有容器的原因,因为它们已经过仔细编写、审查和测试以避免此类错误。
如果您确实需要直接处理原始内存,通常最好编写您自己的容器,您可以按照类似的标准对其进行测试,而不是将手动内存管理与其余的程序逻辑交织在一起。
and I wanted to know if there is some build-in workaround in C++ that will always prevent user when trying to construct unallocated memory
不,因为这必然会导致 运行 编写时不正确的内容的时间成本。我不希望我的程序 运行 变慢,因为其他人 他们的 工作做得不好。
但是,有很多工具可以帮助您测试和诊断这些错误,例如:
- clang 和 gcc 编译器有地址清理器,可以将这些检查编译到您的程序中(这是一个可选的编译器工具,而不是语言的一部分)
- valgrind 是一个外部程序,其默认工具 (memcheck) 运行 是查找这些错误的真实程序。它很慢,但它用于测试或调试而不是用于实时程序
所以我对C++比较陌生,最近遇到了std::allocator
class。我知道这是用于创建 vector
s、list
s、deque
s 等的强大工具,我正在尝试了解更多相关信息。
让我感到困惑的一件事如下:
例如,如果我们定义一些 allocator<int>
表示为 alloc
,我们使用它通过 auto const b = a.allocate(n)
在内存中分配 n
个位置,其中 b
是指向分配内存中第一个 int
元素的指针,那么,为了实际访问它,也有义务构造分配内存,对吧?
如果我们引入一些迭代指针 auto e=b
,那么可以通过 alloc.construct(e++,int_obj)
执行构造,其中 int_obj
是类型 int
的某个用户初始化对象。只要对 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 的数字,即使我只为一个数字分配了 space。那已经是危险信号了,对吧?然后我将 n
更改为 2
,程序在打印数字四后中断,这更符合我的预期。
我从这种行为中得出的结论是,尝试通过 std::allocator
构建尚未分配的内存是未定义和不可预测的,因此应该避免(一开始就很明显)。但是,这似乎是一个极其危险的陷阱,我想知道 C++ 中是否有一些内置的解决方法,在尝试构造未分配的内存时总是会阻止用户。
But, this seems as as extremely dangerous pitfall,
这当然是,您有责任避免这种陷阱。这就是为什么始终建议首先使用现有容器的原因,因为它们已经过仔细编写、审查和测试以避免此类错误。
如果您确实需要直接处理原始内存,通常最好编写您自己的容器,您可以按照类似的标准对其进行测试,而不是将手动内存管理与其余的程序逻辑交织在一起。
and I wanted to know if there is some build-in workaround in C++ that will always prevent user when trying to construct unallocated memory
不,因为这必然会导致 运行 编写时不正确的内容的时间成本。我不希望我的程序 运行 变慢,因为其他人 他们的 工作做得不好。
但是,有很多工具可以帮助您测试和诊断这些错误,例如:
- clang 和 gcc 编译器有地址清理器,可以将这些检查编译到您的程序中(这是一个可选的编译器工具,而不是语言的一部分)
- valgrind 是一个外部程序,其默认工具 (memcheck) 运行 是查找这些错误的真实程序。它很慢,但它用于测试或调试而不是用于实时程序