开发者

Allocating large amount of memory and usage of size_t?

开发者 https://www.devze.com 2023-04-09 03:14 出处:网络
In my application ,I am allocating memory to store \"volume data\" which read from stack of bitmap images.

In my application ,I am allocating memory to store "volume data" which read from stack of bitmap images.

I stored the data in a "unsigned char" and ,during allocation, first I try to allocate continuous memory-block for entire data.if that fails then tries for scattered allocation.(one small memory-block for each image).

unsigned char *data;

here is my method to allocate memory,I call with "tryContinouseBlock=true".

 bool RzVolume::initVolumeData(int xsize, int ysize, int zsize, int bbpsize,bool tryContinouseBlock) {
        this->nx = xsize;
        this->ny = ysize;
        this->nz = zsize;
        this->bbp_type=bbpsize;

        bool succ = false;

        if (tryContinouseBlock) {
            succ = helper_allocContinouseVolume(xsize, ysize, zsize, bbpsize);
        }

        if (!succ) {
            succ = helper_allocScatteredVolume(xsize, ysize, zsize, bbpsize);
        } else {
            isContinousAlloc = true;
        }
        if (!succ) {
            qErrnoWarning("Critical ERROR - Scattered allocation also failed!!!!");
        }
        return succ;

    }



    bool RzVolume::helper_allocContinouseVolume(int xsize, int ysize, int zsize,
            int bbpsize) {
        try {
            data = new unsigned char*[1];
            int total=xsize*ysize*zsize*bbpsize;
            data[0] = new unsigned char[total];
         开发者_开发百科   qDebug("VoxelData allocated - Continouse! x=%d y=%d Z=%d bytes=%d",xsize,ysize,zsize,xsize * ysize * zsize * bbpsize);
        } catch (std::bad_alloc e) {
            return false;
        }

        return true;

    }

bool RzVolume::helper_allocScatteredVolume(int xsize, int ysize, int zsize,
        int bbpsize) {
    data = new unsigned char*[zsize];
    //isContinousAlloc=false;
    int allocCount = 0;
    try { //Now try to allocate for each image
        for (int i = 0; i < zsize; i++) {
            data[i] = new unsigned char[xsize * ysize];
            allocCount++;
        }
    } catch (std::bad_alloc ee) {
        //We failed to allocated either way.Failed!

        //deallocate any allocated memory;
        for (int i = 0; i < allocCount; i++) {
            delete data[i];
        }
        delete data;
        data = NULL;
        return false;
    }
    qDebug("VoxelData allocated - Scattered!");
    return true;
}

I want this code to run in both 32bit and 64bit platforms.

Now the problem is, even in 64Bit environment (with 12Gb memory) ,helper_allocContinouseVolume() method fails when I load (1896*1816*1253) size of data (with bbpsize=1). Its because of, I use "int" datatype for memory address access and the maxmum of "int" is 4294967295.

In both 32bit and 64bit environment following code gives the value "19282112".

 int sx=1896;
 int sy=1816;
 int sz=1253;
 printf("%d",sx*sy*sz);

where the correct value should be "4314249408".

So which datatype should I use for this ? I want to use the same code in 32bit and 64bit environments.


I encounter the same problem very often when working on workstations with > 32GB of memory and large datasets.

size_t is generally the right datatype to use for all indices in such situations as it "usually" matches the pointer size and stays compatible with memcpy() and other library functions.

The only problem is that on 32-bit, it may be hard to detect cases where it overflows. So it may be worthwhile to use a separate memory computation stage using the maximum integer size to see if it's even possible on 32-bit so that you can handle it gracefully.


size_t is defined to be large enough to describe the largest valid object size. So generally, when allocating objects, that is the right size to use.

ptrdiff_t is defined to be able to describe the difference between any two addresses.

Use the one that fits your purpose. That way you'll be ensured it has the appropriate size.


Use ptrdiff_t from <stddef.h>.

Reason: it's signed, thus avoiding the problems with implicit promotion where unsigned is involved, and it has the requisite range on any system except 16-bit (in the formal it works nicely also on 16-bit, but that's because the formal has the silly requirement of at least 17 (sic) bits).

0

精彩评论

暂无评论...
验证码 换一张
取 消