使用memcpy()给C++ 多维vector的快速拷贝赋值问题

博客讨论了在C++中如何正确地使用memcpy()函数将大量浮点数据从字节流中赋值给一个由std::vector<std::vector<float>>实现的二维数组。由于vector的内部结构,直接使用memcpy会导致段错误。解决方案是通过循环在每一维上分别使用memcpy(),确保数据正确地分配到每个子数组中。博客强调了理解vector内存布局的重要性,并提供了修复问题的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我想快速把从一个点云bin文件里读取的十几万或者几十万个点的数据(每个点有(x,y,z,i)四个float类型的值)以字节形式从文件里读取出来后,快速赋值给一个用std::vector<std::vector<float>>实现的二维数组,用memcpy()拷贝字节数据到这个二位数组data()指向的地址,发现这样作后在后面读取这个数组的数据时总是发生segment fault错误而崩溃。

网上搜了很久没找到类似的问题,找资料重新琢磨了一下vector存储数据的内存结构组织形式,发现,当vector嵌套有多维时,其全部数据并不是线性顺序存放的(这和我们平时熟悉的NVIDIA CUDA实现多维数组的线性化存储是不一样),例如说二维时,第一维的数组的每个element的地址里存放的是这个element对应的子数组的首地址(但不是子数组的数据内容存储地址!),就好比指向指针的指针,所以赋值时不能一次借助memcpy()给这种在存储上并不连续的二维数组赋值,需要在第一维度的数组上进行循环,获取每个子数组的地址,再使用memcpy()给每个字数组拷贝赋值,这样才是正确的赋值方式。给出代码实例:

int data_length = 0;
char *data = nullptr;
int ret = read_binary_file(pc_file, &data, &data_length);
if (ret != 0) {
   std::cout <<"failed to read point cloud " << pc_file << std::endl;
   return -1;
}

float* fdata = reinterpret_cast<float*>(data);
int point_num = data_length/16;
std::vector<std::vector<float>> points(point_num, std::vector<float>(4, -100));

// 这样赋值会导致后面读取数据时崩溃
// memcpy(points.data(), fdata, data_length);

for (int i=0; i < point_num; i++) {
   memcpy(points[i].data(), fdata+ 4*i, 16);
   //也可以下面这样赋值,子数组地址一定要使用第一个元素的地址!!! 使用&points[i]也是错的!
   // &points[i]是字数组的首地址但是不是存放数据的地址!需要使用data()获取或使用其第一元素的地址
   // memcpy(&points[i][0], fdata+ 4*i, 16);
}
delete fdata;

//读取数据进行voxelization处理
...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arnold-FY-Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值