据我所知,调用malloc()
基本上意味着该程序正在向操作系统询问一大块内存。我正在编写一个程序来与摄像头连接,我需要在其中分配足够大的内存,以便一次存储数百个图像(它是一个快速的摄像头)。
当我为大约1.9 Gb的图像分配空间时,一切正常。分配计算非常简单:
int allocateBurst( int numImages )
{
int streamSize = ZIMAGESIZE * numImages;
data.images = new unsigned short [streamSize];
return 0;
}
但是当我超过2 Gb限制时,我会遇到这样的运行时错误:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
看起来2 Gigs可能是我一次可以分配的最大尺寸。我有32 Gig的ram,并希望能够在一次分配中分配更大的内存。这可能吗?
我正在运行Ubuntu 12.10。
答案 0 :(得分:1)
可能存在一个潜在的问题,操作系统无法授予您大量内存分配,因为它正在为其他应用程序使用内存。请查看您的操作系统,了解限制是什么。
也知道有些操作系统会将内存“页”到硬盘上。当程序要求页面外的内存时,操作系统将与硬盘交换页面。知道这一点,我推荐一种经典的“双缓冲”或“多次缓冲”技术。
您至少需要两个线程:阅读和写作。一个线程负责从相机读取数据并放入缓冲区。当它填满缓冲区时,它从另一个缓冲区开始。同时写入线程从缓冲区开始并将其写入磁盘(块文件写入)。当写入线程完成缓冲区时,它将从下一个开始。缓冲区应该是循环序列以重复使用它们。
神奇的是要有足够的缓冲区,以便读者永远不会赶上作家。
由于您使用了几个小缓冲区,因此不应该从操作系统中获得任何错误。
优化此方法的方法,例如从OS获取静态缓冲区。
答案 1 :(得分:1)
问题是您使用带符号的32位变量来描述无符号的64位数字。
使用“size_t”而不是“int”来保存存储计数。这与您打算存储的内容无关,只需要多大的数量。
#include <iostream>
int main(int /*argc*/, const char** /*argv*/)
{
int units = 2;
// 32-bit signed, i.e. 31-bit numbers.
int intSize = units * 1024 * 1024 * 1024;
// 64-bit values (ULL suffix)
size_t sizetSize = units * 1024ULL * 1024ULL * 1024ULL;
std::cout << "intSize = " << intSize << ", sizetSize = " << sizetSize << std::endl;
try {
unsigned short* intAlloc = new unsigned short[intSize];
std::cout << "intAlloc = " << intAlloc << std::endl;
delete [] intAlloc;
} catch (std::bad_alloc) {
std::cout << "intAlloc failed (std::bad_alloc)" << std::endl;
}
try {
unsigned short* sizetAlloc = new unsigned short[sizetSize];
std::cout << "sizetAlloc = " << sizetAlloc << std::endl;
delete [] sizetAlloc;
} catch (std::bad_alloc) {
std::cout << "sizetAlloc failed (std::bad_alloc)" << std::endl;
}
return 0;
}
输出(在具有4Gb内存的虚拟机上,gint 15 64位,g ++ 4.7.3下的g ++ -m64 -o test test.cpp)
intSize = -2147483648, sizetSize = 2147483648 intAlloc failed sizetAlloc = 0x7f55affff010
答案 2 :(得分:-2)
int allocateBurst( int numImages )
{
// change that from int to long
long streamSize = ZIMAGESIZE * numImages;
data.images = new unsigned short [streamSize];
return 0;
}
尝试使用
long
OR
将allocateBurst函数的结果转换为“uint_64”,并将函数的返回类型转换为uint_64
因为int你在长时间内分配32位分配,或者uint_64分配64位分配,这可能为你分配更多的内存空间。
希望有所帮助