我想动态分配已知大小的内存(只是内存,不打扰类型),并用完全相同数量的数据填充它,但任何类型(我只确定它是原始类型)。之后我会释放它。
可以吗? :
auto dest = new int8_t[n];
std::memcpy(dest, src, n);
delete[] dest;
src
是一个大小为n
(字节)的数组的ptr。
我选择int8_t
因为它是分配一定数量内存的最清晰方式。
事实上,上面的代码并不能说明它将会是什么。对于实际指向的类型指针,将调用delete[]
。
因此,例如,如果src是一个浮点数组(忘记上面代码的最后一行):
float * ptr = dest;
delete[] ptr;
再一次。会没事吗?
答案 0 :(得分:6)
没关系,但只有当你使用unsigned char
数组或delete
数组时才会这样,因为这些类型有特殊的对齐保证:
5.3.4新
11当new-expression调用分配函数时 分配还没有扩展,new表达式通过了 作为第一个请求分配功能的空间量 std :: size_t类型的参数。那个论点应该不低于 正在创建的对象的大小;它可能大于 仅当对象是数组时才创建的对象。 对于数组 char和unsigned char ,结果的区别 new-expression和分配函数返回的地址 应该是最严格的基本对齐的整数倍 要求(3.11)任何大小不大于的对象类型 正在创建的数组的大小。 [注意:因为分配 假设函数返回指向存储的指针 适当地对齐任何类型的对象与基本对象 对齐,这种对数组分配开销的约束允许 分配字符数组的常用习惯用法 稍后将放置其他类型。 - 结束注释]
我的重点。
另一个要求是你只使用原始类型或POD,因为你没有调用构造函数,而是(普通的)析构函数(通过C:\Program Files (x86)\Git\bin\ssh.exe
)。
答案 1 :(得分:3)
根据new expression
执行new int8_t[n]
来电operator new[](sizeof(int8_t)*n + overhead)
的说明。
关于间接费用的重要说明:
许多实现使用数组开销来存储数组中的对象数,delete []表达式使用它来调用正确数量的析构函数。
反过来,operator new[](std::size_t count)
返回指向已分配内存块的void*
指针。此指针还应在delete []
表达式中使用。
你有简单的类型没有析构函数,所以delete[]
只需要释放内存块。它可以安全地使用int8_t* dest
或float* ptr
。
更新的:
最好将数组类型从int8_t
更改为char
或unsigned char
。对于具有此类C ++标准保证的数组,您将获得进一步数据放置的适当对齐。谢谢@alain。更多细节和标准报价可以在他的答案中找到。
答案 2 :(得分:2)
使用标准矢量可能会更好吗?无需手动释放内存..
std::vector<uint8_t> vdest(n);
uint8_t * dest = vdest.data();
std::memcpy(dest, src, n);
float * ptr = reinterpret_cast<float*>(dest);
...
编辑: 正如@alain所指出的那样:&#34;无法保证uint8_t数组与新类型正确对齐&#34;
因此,如果你想使用这种方法,最好先看看这个问题:Is it good practice to use std::vector as a simple buffer?
答案 3 :(得分:0)
我了解这是实时编程中的常见情况。为了确保每个结构都与uint8_t / unsigned char(任何自定义的字节大小数据类型)对齐,请确保每个结构(除原始数据结构外)都使用概念#pragma pack。