0

I already searched for an answer here, but I couldn't find something that suits my case.

I have a function make_array(), which generates a 2-dimensional array, and has to fill it with zeros. When calling this function in main() and printing the values, there's a strange output, which is non-reproducible on other machines...

[...]    
Valuearray[0][13]: 0
Valuearray[0][14]: 65
Valuearray[0][15]: 0
[...]

The rest of the array contains Zeros. Searching for an answer I randomly changed

Array[i][j] = 0;

to

Array[i][j] = 123;

and got

Valuearray[0][0]: 0
Valuearray[0][1]: 0
Valuearray[0][2]: 0
Valuearray[0][3]: 0
Valuearray[0][4]: 0
Valuearray[0][5]: 0
Valuearray[0][6]: 0
Valuearray[0][7]: 0
Valuearray[0][8]: 0
Valuearray[0][9]: 0
Valuearray[0][10]: 0
Valuearray[0][11]: 0
Valuearray[0][12]: 0
Valuearray[0][13]: 0
Valuearray[0][14]: 65
Valuearray[0][15]: 0
Valuearray[0][16]: 123
[...]

the rest contains 123. So just the first 16 Elements don't get changed by the for-loop.

The code of my program:

//#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

const int global_file_count = 10;
const int global_max_x_coord = 309;
const int global_min_x_coord = 111;


int** make_array(int SizeY, int SizeX){ // SizeY=global_file_count+1, 
                                        // SizeX=global_max_x_coord-global_min_x_coord

    //http://pleasemakeanote.blogspot.de/2008/06/2d-arrays-in-c-using-malloc.html

    int** Array;  
    Array = (int**) malloc((SizeX)*sizeof(int*)); 
    for (int i = 0; i < SizeX; i++) {
       Array[i] = (int*) malloc((SizeY)*sizeof(int));
   }

    for (int i=1;i<=SizeY;i++){ // should fill everything element with 0 (????)
        for(int j=0;j<=SizeX;j++){
                Array[i][j] = 123;
        }
    }

return Array;
    free(Array);
}

int main(){

    int** Valuearray = make_array(global_file_count+1, (global_max_x_coord-global_min_x_coord));

    for (int i=0;i<=global_file_count+1;i++){
        for(int j=0;j<=(global_max_x_coord-global_min_x_coord);j++){
                printf("Valuearray[%i][%i]: %i\n", i, j, Valuearray[i][j]);
        }
    }
    free(Valuearray);
}

Also, when I plant an extra

Array[0][14] = 0;

before

return Array;

in my make_array()-function, everything is fine and the value gets changed. But I'd really rather let my for-loop do this...

My question is: As it this non-reproducible, what can I do about it? And what is the reason for this? I am using Ubuntu 12.10., Sublime Text 2 as IDE, and gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 as Compiler, if this information is useful. Thanks in advance and sorry for this big pile of text.

pxlbrnd
  • 5
  • 4
  • side note : `free(ValueArray)` isn't sufficient to de-allocate this 2D array. You need to have a `free` corresponding to every `malloc`. – Sander De Dycker May 10 '13 at 15:43
  • You are not constructing a 2D array but only an emulation with it through pointers to pointers. There is no need to do this in C. Also don't cast the return of `malloc`, this may hide sutle bugs. – Jens Gustedt May 10 '13 at 15:50
  • "As it this non-reproducible" **undefined behavior** rarely *is* consistently reproducible, and there is plenty of it in this code. Check your array indexing (remember, C is 0-based through (N-1) for a N-sized array). Likewise, as Sander pointed out, this leaks everything allocated except the pointer vector, which is ironic in that it is required for accessing all the sub-vectors for `free()`ing. Once it is gone, the others are unreachable. – WhozCraig May 10 '13 at 15:53

3 Answers3

2

Try this

for (int i=0;i<SizeX;i++){ // should fill everything element with 0 (????)
    for(int j=0;j<SizeY;j++){
            Array[i][j] = 0;
    }
}

or replace malloc() with calloc() instead of the above for loop.

akhil
  • 732
  • 3
  • 13
1

You swapped SizeX and SizeY when filling in the array, this is correct:

for ( i=0;i<SizeX;i++){ // should fill everything element with 0 (????)
    for( j=0;j<SizeY;j++){

Additionally, you are indexing one too many times in your loops, for example:

for (int i=1;i<=SizeY;i++)
             ^^^^^^^^

should be:

for (int i=1;i<SizeY;i++)

So you are going out of bounds which is undefined behavior. Also, this this previous thread on free'ing 2D arrays.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
1

When filling the array, you need to swap around the use of SizeX and SizeY, since SizeX is the range of the first index, and SizeY of the second.

Additionally, you need to start indexing at 0, and end at size - 1 (for whatever the size is).

So :

for (int i = 0; i < SizeX; i++) {
    for (int j = 0; j < SizeY; j++) {
        Array[i][j] = 123;
    }
}

(note that you'll also have to fix the indexes in the loop that prints the contents of the array)

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40