CuriousCat
CuriousCat

Reputation: 419

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

Upvotes: 0

Views: 634

Answers (1)

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140256

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)

Upvotes: 8

Related Questions