语言:C ++
系统:Windows 7 x64
内存:8GB RAM
我想在我的64位应用程序中新建一个大的一维数组,其中包含60000 * 60000 = 3600000000无符号的短类型元素。
目的是读取一张非常大的60k * 60k像素的图片,并将其转换为一维数组以进行进一步处理。我当然可以拆分图片并单独阅读,但是在生产环境中,确实有128GB和更多的RAM需要消耗。
unsigned short array [3600000000];
它显示 错误:数组'a'的大小为负数
unsigned long long bytes = 3600000000 * sizeof(unsigned short);
unsigned short *arr;
arr = (unsigned short *)malloc(bytes);//almost 6.7GB memory
在具有8GB RAM的PC中,在malloc行调试时arr的地址为0x0
在其他具有16GB RAM的PC中,arr的地址有效,但是如果我将值分配给arr中的每个项目,例如
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
unsigned short *arr;
arr = (unsigned short *)malloc(3600000000 * sizeof(unsigned short));//memory space can be allocate to arr, about 6.7GB
if (arr == NULL){
cout << "failed"<< endl;
}
memset(arr, 1, sizeof(arr));
cout << arr << endl;
}
在某些奇怪的内存位置处会发生中断,arr为0x11103630A52B112。
在具有8GB RAM的PC x64中,它显示“失败”
在具有16GB RAM的其他PC x64中,arr的地址有效,但是如果我使用for循环为arr中的每个项目分配值,则将在某些有线存储位置发生中断arr为0x11103630A52B112
我怎么能新建一个非常大的一维数组
1.(静态方法8GB)它显示 错误:数组'a'的大小为负
2.(malloc方法为8GB)error log with my 8GB and memset statement
oneDimensionalArray.cpp: In function 'int main()':
oneDimensionalArray.cpp:10:47: warning: unsigned conversion from 'long long int' to 'size_t' {aka 'unsigned int'} changes value from '7200000000' to '2905032704' [-Woverflow]
arr = (unsigned short *)malloc(3600000000 * sizeof(unsigned short));//memory space can be allocate to arr, about 6.7GB
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
oneDimensionalArray.cpp:10:35: warning: argument 1 value '2905032704' exceeds maximum object size 2147483647 [-Walloc-size-larger-than=]
arr = (unsigned short *)malloc(3600000000 * sizeof(unsigned short));//memory space can be allocate to arr, about 6.7GB
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\cstdlib:75,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\ext\string_conversions.h:41,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\bits\basic_string.h:6391,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\string:52,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\bits\locale_classes.h:40,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\bits\ios_base.h:41,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\ios:42,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\ostream:38,
from folderPath\mingw\installed\lib\gcc\mingw32\8.2.0\include\c++\iostream:39,
from oneDimensionalArray.cpp:1:
folderPath\mingw\installed\include\stdlib.h:503:40: note: in a call to allocation function 'void* malloc(size_t)' declared here
_CRTIMP __cdecl __MINGW_NOTHROW void *malloc (size_t) __MINGW_ATTRIB_MALLOC;
^~~~~~
failed
3.(malloc方式为16GB) 引发了一个异常:写访问权限冲突,分配语句 arr [i] = 1时arr为0x11103630A52B112 ; for循环
答案 0 :(得分:9)
您所在的行:
unsigned long long bytes = 3600000000 * sizeof(unsigned short);
对于分配的内存量,这看起来是正确的,但是您也可以使用相同的值来遍历数组:
for(long long i = 0; i<bytes;i++){
arr[i] = 1;
}
这是错误的,数组中只有3600000000
个元素,而不是3600000000 * sizeof(unsigned short)
。您正在写超出分配的内存末尾的内容。
答案 1 :(得分:1)
除了@Blastfurnace关于使用太大索引的良好观察:
“其他具有16GB RAM的电脑,arr
的地址有效”中可能存在溢出
如果size_t
是32位,则malloc(bytes)
会将大于bytes
的{{1}}转换为比SIZE_MAX
小得多的值。返回一个有效的指针,但不是所需的大小。
使用3600000000 * sizeof(unsigned short)
代替unsigned long long bytes
,启用所有警告并注意数学size_t bytes
不会溢出。
3600000000 * sizeof(unsigned short)
读取一张非常大的图片,其大小为60k * 60k像素
要解决OP的更高问题,请不为60k * 60k #if 3600000000 > SIZE_MAX/sizeof(unsigned short)
#error overflow
#endif
size_t bytes = 3600000000 * sizeof(unsigned short);
数组分配3600000000 * sizeof(unsigned short)
字节。
相反,为60k unsigned short
个数组分配60k次。
(OP正在使用C ++,但似乎要使用unsigned short
。malloc()
会更像C ++。)
new