tags:

views:

145

answers:

4

I believe the malloc is badly assigned, why?

 int ** array;
  int i,j;

  array=malloc(10*sizeof(int *));

  for(i=0; i<10; i++)
    for (j=0;j<10; j++)
        array[i][j]=i*j;
+6  A: 

it should be malloc(10*10*sizeof(int));

there are two methods of creating 2d arrays in c: using continuous memory or using array of pointers. In first case you malloc 10*10 consecutive elements and access is done like this: array[i][j] = *(array + i*10 + j) = array[i*10 + j] (don't forget that hardcoding constants is smell). In other case you malloc 10 elements of type int* then you malloc rows in loop. then access like this array[i][j] = *(*(array + i) + j)

Andrey
And `array[i][j]` should be replaced with `array[i*10+j]`.
@user470379 you are right, i fixed it
Andrey
In case you're allocating "just one block", `array` should be of type `int *`, not `int **`.
Alok
+3  A: 

The problem is that your array is 10x10 = 100 elements, but you are mallocing only 10 elements' worth of space (incidentally, the comment above is correct: malloc for sizeof(int), not sizeof(int*) since int is what you actually want to store in the array).

If you change the malloc to

malloc(100 * sizeof(int))

then you should be fine.

EDIT: Just noticed that you are declaring it as int**. For a rectangular array like this you can declare it as int* and index by (j * 10 + i). Otherwise, you'll have to malloc the first dimension, then malloc each entry for the second dimension. This is slow and bug-prone, so better to use the j*10+i method.

Cameron Skinner
+7  A: 

You have a two-dimensional array so you need to allocate enough space to hold 100 elements. Alternatively, you need to allocate each column (per row) before you put things in that row. I'd only do the latter if the array were a jagged array, having different numbers of elements per row.

array=malloc(100*sizeof(int)); 

for(i=0; i<10; i++) 
  for (j=0;j<10; j++) 
    array[i*10+j]=i*j; 

or

array=malloc(10*sizeof(int *)); // rows

for(i=0; i<10; i++) {
  array[i] = malloc(10*sizeof(int));  // columns
  for (j=0;j<10; j++) 
      array[i][j]=i*j;
}
tvanfosson
`array[i*10+j]=i*j;` in second case will not work
Andrey
In the second case it should be `array[i][j]` not using index arithmetic. Also in the first case the type of `array` should be changed to `int*`.
sepp2k
Yeah -- cut/paste error. I'll fix it.
tvanfosson
Why was this downvoted? Sounds reasonable to me.
Cameron Skinner
@Cameron Skinner i downvoted because there was an error
Andrey
@Cameron - Probably because when I originally wrote it I ignored the issue of indexing into the array, simply doing a cut/paste on the original. When I saw the mistake, I edited it but mistakenly made the change in both code bits (which was also wrong). I've fixed it now. I was simply too focused on the allocation issue and ignored the rest of the code originally then "fixed" it without thinking.
tvanfosson
@Andrey - so now that it's fixed, you'll retract? :-)
tvanfosson
@Andrey OK, fair enough. It must have been fixed by the time I saw it :)
Cameron Skinner
@tvanfosson i removed my downvote
Andrey
@Andrey -- thanks.
tvanfosson
A: 

You've allocated the memory for your first dimension, but not the second.

size_t rows = 10;
size_t cols = 10;
int **array = malloc(sizeof *array * rows); // allocates array of 10 int *
if (array)
{
  size_t i;
  for (i = 0; i < rows; i++)
  {
    array[i] = malloc(sizeof *array[i] * cols); // allocates array of 10 int
    if (array[i])
    {
      size_t j;
      for (i = 0; i < cols; i++)
        array[i][j] = i * j;
    }
  }
}

Note that this does not allocate a contiguous block of memory; if you need all 100 elements to be contiguous, you have several choices:

Choice 1: Allocate a 1-D array and compute offsets manually as several others have shown;

Choice 2: Allocate a 1-D array and use an array pointer and some casting magic to make it look like a 2-D array:

#define COLS 10

size_t rows = 10;
size_t cols = COLS;
int *array = malloc(sizeof *array * rows * cols);
int (*parr)[COLS] = (int (*)[COLS]) array;
if (array)
{
  size_t i, j;
  for (i = 0; i < rows; i++)
    for (j = 0; j < cols; j++)
      parr[i][j] = i * j;
}

The drawback is that to declare the pointer you have to know how many columns you're working with, and for C89 you have to use a compile-time constant expression for the column dimension, which kind of defeats the purpose of dynamic allocation (using the cols variable wouldn't work unless you were using a C99 compiler).

Choice 3: If you're using C99, you can use a VLA and avoid malloc (and the accompanying free) altogether:

int rows = ROWS;
int cols = COLS;

int array[rows][cols];

for (int i = 0; i < rows; i++)
  for (int j = 0; j < cols; j++)
    array[i][j] = i * j;
John Bode