Search code examples
c++cmalloccallocdata-management

calloc overwrites another variable's memory?


I am writing a program to create a gray scale image (image) using calculations on data stored in source array (hist). The data stored in source array resets to zero after calling calloc for image.

func1(){
    float * hist = (float *) calloc(256, sizeof(float));
    // operation to populate 'hist'
    for...{
       for...{
           hist.....
       }
    }

    hist2img(hist);
    free(hist);
    return 0;
}

hist2img(hist){
    cout << "-> " << hist [4 * 250] << endl;

    unsigned char * image = (unsigned char *) calloc(256 * 256, sizeof(unsigned char));

    cout << "-> " << hist [4 * 250] << endl;

    free(image);
    return 0;
}

the output is:

-> 0.997291
-> 0

What happens to the data? All elements in hist are 0 after the calloc instruction. I need image to be initialized to 0.

--(~$)--> gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609

--(~$)--> uname
Linux 4.7.2-040702-generic x86_64 x86_64 x86_64 GNU/Linux

Solution

  • You allocate 256 floats:

    float * hist = (float *) calloc(256, sizeof(float));
    

    and you access to the 1000th element, which is UB

    cout << "-> " << hist [4 * 250] << endl;
    

    The calloc call zeroes some memory that you were mistakingly pointing to

    To gain access to the 250th float element of hist, just

    cout << "-> " << hist [250] << endl;
    

    (since hist is a pointer on float, the compiler computes addresses by multiplying float size, no need to do that yourself)

    If you know the size in advance, it's even better to allocate data statically

    declaration:

    float hist[256]={0};
    

    When defining hist2img:

    hist2img(float hist[256]){
    

    in that case you get a warning when static index is going out of range (but still crashes/UB if some variable index is going off-bounds: there are no run-time checks)