发现问题了。 问题代码:
qint64 dataSize = 2701131776;
char* yuanshuju = new char[dataSize];
可行代码:
char* yuanshuju = new char[2701131776];
c++,牛 我反正是没搞懂
1
yougg 276 天前 3
先把变量名改为 metadata 吧, 看到这里就难受无法继续阅读了......
|
2
proxytoworld 276 天前
同意一楼的
|
4
deplives 276 天前
这个 yuanshuju 血压升高
|
5
Mithril 276 天前 4
用 memory mapping ,不要手动去读它。
|
6
silentx 276 天前
是啥东西要一次性读到内存里处理?不考虑分段读吗?不是每个人的机器都是 32G 内存起步的啊。。。
|
7
maokg 276 天前
不知道一次性读 2.51GB 数据的应用场景是什么
|
9
geelaw 276 天前 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 |
11
Crawping 276 天前
理论 64 位程序的寻址空间是可以到 2'64 次字节
```C++ //你是真的这么写的 还是手写拷贝的? 中间为啥会有 ',' 逗号 char* yuanshuju = new char[2,701,131,776] ``` 学其他语言问 GPT 比发帖要来得快 |
15
tool2d 276 天前
我用 malloc ,别说是 malloc(2701131776)可以, 就算 malloc(4701131776)也行。
应该只是你内存不够的原因。”不够“不是说总剩余内存不够,而是无法分配一块巨大内存。 |
16
shuax 276 天前
改成 64 位轻轻松松。
|
17
greycell 276 天前
笑死,元数据 2 个 g ,还在嘴硬。
|
18
MoYi123 276 天前 1
建议发一下编译器的版本
或者试试看这样写 auto alloc = vector<int64_t>(2701131776 / 8 + 1); char* yuanshuju = reinterpret_cast<char*>(alloc.data()); |
19
clue 276 天前
能流式处理不? 为什么一定要全读到内存里?
|
20
royking930911 276 天前
从原数据着手吧 一次申请几个 G 的内存就算这次运行不出问题 下次也会崩
修改方法:1,分段读取 分段解析 2,优化算法 保存分段前后缓存数据和状态 |
21
yuzii 276 天前
|
22
yolee599 276 天前
这么大一个数组,我看着都头疼,考虑分多次处理吧,每次大概分配 4096 字节
|
23
shawnsh 276 天前 via Android
大力出奇迹啊,先设计设计
|
24
SmartTom OP 发现问题了。
问题代码: qint64 dataSize = 2701131776; char* yuanshuju = new char[dataSize]; 可行代码: char* yuanshuju = new char[2701131776]; c++,牛 我反正是没搞懂 |
27
Geekerstar 276 天前
我还以为是 yushengjun (余胜军)
|
28
amorphobia 276 天前
|
29
vsomeone 276 天前 1
根据你给的附言,推测可能是你 qtglobal 头文件引入的有问题,导致 qint64 被认为是 int32_t 。因为 2701131776 > INT_MAX(1 << 32 - 1),这个值在 assign 给 int32_t dataSize 之后被认为是一个负数,导致 bad_alloc 。
|
30
vsomeone 276 天前
@amorphobia 他这个不是变长数组呀,用了 new 分配在堆上的,变长数组指的是分配在栈上的
|
31
nagisaushio 276 天前 via Android
这么大文件为什么不 mmap?
|
32
MrKrabs 276 天前
2.51G 就大了?你们用的都是黄金内存吗
|
33
amorphobia 276 天前 via iPhone
@vsomeone 是我想错了
|
34
march1993 276 天前
一个动态申请的,一个是放在静态区的?
|
35
JustdoitSoso 276 天前 via Android 1
@vsomeone 感觉你说的是最有可能得情况,人家来请教问题,一群没分析没讨论的在说变量命名。
|
36
yuruizhe 276 天前
试试用
constexpr qint64 dataSize = 2701131776; 行不行? |
37
NEO17 276 天前
看了这段代码,不建议再写 C++ :)
|
38
litguy 276 天前
这个不是应该 mmap 的方式访问么 ?
|
39
araraloren 276 天前
Why you need load whole data to memory?
|
40
ltyj2003 276 天前 via Android
动态长度用 vector
或者定义一个 char* ,然后 malloc 分配内存空间。 |
41
cnbatch 276 天前
@amorphobia 这么大的 VLA ,存在爆栈的可能性吧(视乎编译器做法而定)
|
42
amorphobia 276 天前
|
43
cnbatch 276 天前 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 ,就可以跳过这一步,它们都会自动初始化。 |
45
yougotme 275 天前 via iPhone
vs2022 肯定会抛一个警告出来的,也许你忽略了或者编译器不够新
|