关于 C++读取大小为 2.51 GB (2,701,131,776 字节)到 char* yuanshuju 数组中去

2024-03-21 09:58:00 +08:00
 SmartTom
如题,现在想实现将这个大文件(大小超过 int 最大范围)的文件放入到 char* yuanshuju = new char[2,701,131,776]中
现在就卡在第一步定义 yuanshuju 这一步,qt 一直提示"terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc",本人没太做过 c++,这个提示是代表不能定义那么大的数组吗?还有别的可行方案吗。
系统:win11 64 位
QT: 5.12.12
3473 次点击
所在节点    程序员
45 条回复
cnbatch
2024-03-21 15:44:33 +08:00
@amorphobia 这么大的 VLA ,存在爆栈的可能性吧(视乎编译器做法而定)
amorphobia
2024-03-21 16:13:25 +08:00
@cnbatch

是我想错了,这里不是 VLA

如果真有这么大的 VLA ,我也高度怀疑会爆
cnbatch
2024-03-21 16:19:43 +08:00
等等,为什么要用 new 直接创建呢?最后还得手动 delete 。
不如用 std::vector 或者 std::make_unique<char[]>(数据长度)
这两个好多了

std::vector 已经有人发了,那么 make_unique 的用法是:

size_t data_size{2701131776};
std::unique_ptr<char[]> raw_data_ptr = std::make_unique<char[]>(data_size);
char* raw_data = raw_data_ptr.get();

在我的 Windows 11 + VS2022 测了下,很成功,没任何报错。

另外呢,直接用 malloc 、new 创建的空间,按照 C 语言留下来的“惯例”,是需要手动初始化的。
通常会用 memset 初始化为零,用 std::fill 也可以。

如果改用 std::vector 或者 std::make_unique ,就可以跳过这一步,它们都会自动初始化。
yougotme
2024-03-21 21:39:04 +08:00
@SmartTom 立即数后面加上 LL ,明确指定长度。否则编译器可能会误判你是 int32 转 int64 ,可能变负数、可能溢出。
yougotme
2024-03-21 21:40:25 +08:00
vs2022 肯定会抛一个警告出来的,也许你忽略了或者编译器不够新

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://ex.noerr.eu.org/t/1025635

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX