发现问题了。 问题代码:
qint64 dataSize = 2701131776;
char* yuanshuju = new char[dataSize];
可行代码:
char* yuanshuju = new char[2701131776];
c++,牛 我反正是没搞懂
|  |      1yougg      2024-03-21 10:05:14 +08:00  3 先把变量名改为 metadata 吧, 看到这里就难受无法继续阅读了...... | 
|  |      2proxytoworld      2024-03-21 10:07:34 +08:00 同意一楼的 | 
|      4deplives      2024-03-21 10:13:17 +08:00 这个 yuanshuju 血压升高 | 
|      5Mithril      2024-03-21 10:14:33 +08:00  4 用 memory mapping ,不要手动去读它。 | 
|      6silentx      2024-03-21 10:15:50 +08:00 是啥东西要一次性读到内存里处理?不考虑分段读吗?不是每个人的机器都是 32G 内存起步的啊。。。 | 
|  |      7Yasuke      2024-03-21 10:16:45 +08:00 不知道一次性读 2.51GB 数据的应用场景是什么 | 
|  |      9geelaw      2024-03-21 10:17:06 +08:00  2 new char[2,701,131,776] 会分配长度是 776 个元素的 char 数组,不是你期待的 2.51 GB 。 int main() { new char[2701131776] { }; } 这个程序在我的电脑上编译为 64 位的话可以正常运行,并且确实占用了 2.51 GB 内存,如果用 32 位编译器则编译失败,因为分配的数组规模超过了 size_t 。 抛出 std::bad_alloc 的意思就是分配失败,或许你的页面文件和实体内存不够大。 如果数据来自于文件,可以用内存映射文件,Windows 的文档是 https://learn.microsoft.com/en-us/windows/win32/memory/file-mapping POSIX 的文档是 https://pubs.opengroup.org/onlinepubs/9699919799/functions/mmap.html | 
|      11Crawping      2024-03-21 10:19:25 +08:00 理论 64 位程序的寻址空间是可以到 2'64 次字节 ```C++ //你是真的这么写的 还是手写拷贝的? 中间为啥会有 ',' 逗号 char* yuanshuju = new char[2,701,131,776] ``` 学其他语言问 GPT 比发帖要来得快 | 
|  |      12geelaw      2024-03-21 10:19:53 +08:00  1 @geelaw #9 没有超过 size_t (((φ(◎ロ◎;)φ))) 是 MSVC 只支持至多 2147483647 个元素。 | 
|  |      15tool2d      2024-03-21 10:28:55 +08:00 我用 malloc ,别说是 malloc(2701131776)可以, 就算 malloc(4701131776)也行。 应该只是你内存不够的原因。”不够“不是说总剩余内存不够,而是无法分配一块巨大内存。 | 
|  |      16shuax      2024-03-21 10:31:29 +08:00 改成 64 位轻轻松松。 | 
|      17greycell      2024-03-21 10:32:10 +08:00 笑死,元数据 2 个 g ,还在嘴硬。 | 
|  |      18MoYi123      2024-03-21 10:33:48 +08:00  1 建议发一下编译器的版本 或者试试看这样写 auto alloc = vector<int64_t>(2701131776 / 8 + 1); char* yuanshuju = reinterpret_cast<char*>(alloc.data()); | 
|      19clue      2024-03-21 10:34:32 +08:00 能流式处理不? 为什么一定要全读到内存里? | 
|      20roykingH      2024-03-21 10:37:49 +08:00 从原数据着手吧  一次申请几个 G 的内存就算这次运行不出问题  下次也会崩 修改方法:1,分段读取 分段解析 2,优化算法 保存分段前后缓存数据和状态 | 
|      21yuzii      2024-03-21 10:38:56 +08:00 | 
|  |      22yolee599      2024-03-21 10:47:30 +08:00 这么大一个数组,我看着都头疼,考虑分多次处理吧,每次大概分配 4096 字节 | 
|  |      23shawnsh      2024-03-21 10:51:06 +08:00 via Android 大力出奇迹啊,先设计设计 | 
|  |      24SmartTom OP 发现问题了。 问题代码: qint64 dataSize = 2701131776; char* yuanshuju = new char[dataSize]; 可行代码: char* yuanshuju = new char[2701131776]; c++,牛 我反正是没搞懂 | 
|  |      27Geekerstar      2024-03-21 11:16:39 +08:00 我还以为是 yushengjun (余胜军) | 
|  |      28amorphobia      2024-03-21 12:08:42 +08:00 | 
|      29vsomeone      2024-03-21 12:19:22 +08:00  1 根据你给的附言,推测可能是你 qtglobal 头文件引入的有问题,导致 qint64 被认为是 int32_t 。因为 2701131776 > INT_MAX(1 << 32 - 1),这个值在 assign 给 int32_t dataSize 之后被认为是一个负数,导致 bad_alloc 。 | 
|      30vsomeone      2024-03-21 12:20:19 +08:00 @amorphobia 他这个不是变长数组呀,用了 new 分配在堆上的,变长数组指的是分配在栈上的 | 
|  |      31nagisaushio      2024-03-21 12:24:11 +08:00 via Android 这么大文件为什么不 mmap? | 
|      32MrKrabs      2024-03-21 13:10:14 +08:00 2.51G 就大了?你们用的都是黄金内存吗 | 
|  |      33amorphobia      2024-03-21 14:15:08 +08:00 via iPhone @vsomeone 是我想错了 | 
|      34march1993      2024-03-21 14:24:00 +08:00 一个动态申请的,一个是放在静态区的? | 
|  |      35JustdoitSoso      2024-03-21 14:28:51 +08:00 via Android  1 @vsomeone 感觉你说的是最有可能得情况,人家来请教问题,一群没分析没讨论的在说变量命名。 | 
|      36yuruizhe      2024-03-21 14:43:13 +08:00 试试用 constexpr qint64 dataSize = 2701131776; 行不行? | 
|      37NEO17      2024-03-21 15:04:52 +08:00 看了这段代码,不建议再写 C++ :) | 
|  |      38litguy      2024-03-21 15:28:35 +08:00 这个不是应该 mmap 的方式访问么 ? | 
|  |      39araraloren      2024-03-21 15:30:19 +08:00 Why you need load whole data to memory? | 
|      40ltyj2003      2024-03-21 15:42:10 +08:00 via Android 动态长度用 vector 或者定义一个 char* ,然后 malloc 分配内存空间。 | 
|      41cnbatch      2024-03-21 15:44:33 +08:00 @amorphobia 这么大的 VLA ,存在爆栈的可能性吧(视乎编译器做法而定) | 
|  |      42amorphobia      2024-03-21 16:13:25 +08:00 | 
|      43cnbatch      2024-03-21 16:19:43 +08:00  2 等等,为什么要用 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 ,就可以跳过这一步,它们都会自动初始化。 | 
|  |      44yougotme      2024-03-21 21:39:04 +08:00 via iPhone @SmartTom 立即数后面加上 LL ,明确指定长度。否则编译器可能会误判你是 int32 转 int64 ,可能变负数、可能溢出。 | 
|  |      45yougotme      2024-03-21 21:40:25 +08:00 via iPhone vs2022 肯定会抛一个警告出来的,也许你忽略了或者编译器不够新 |