0

All the solutions I have seen online has calloc() function used twice, is it possible to do with only using it once? The below code is not printing the correct array elements

int **ptr;

//To allocate the memory 
ptr=(int **)calloc(n,sizeof(int)*m);

printf("\nEnter the elments: ");

//To access the memory
for(i=0;i<n;i++)
{  
 for(j=0;j<m;j++)
 {  
  scanf("%d",ptr[i][j]);
 }
}
  • The problem with your code is, how does the pointer know the dimensions of your array? It needs those dimensions to calculate the correct memory address. That's why it only works directly with one-dimensional arrays. – Blaze Oct 05 '18 at 08:51
  • 1
    Possible duplicate: [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Lundin Oct 05 '18 at 09:24
  • 3
    Possible duplicate of [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) @Lundin Hammer time – Stargateur Oct 05 '18 at 09:26
  • @Stargateur I try to avoid dupe-hammering to questions/answers posted by myself, unless they are community wikis or such. – Lundin Oct 05 '18 at 09:28

2 Answers2

4

Since C99 you can use pointers to VLAs (Variable Length Arrays):

int n, m;

scanf("%d %d", &n, &m);

int (*ptr)[m] = malloc(sizeof(int [n][m]));

for (i = 0; i < n; i++)
{  
    for (j = 0; j < m; j++)
    {  
        scanf("%d", &ptr[i][j]); // Notice the address of operator (&) for scanf
    }
}
free(ptr); // Call free only once
David Ranieri
  • 39,972
  • 7
  • 52
  • 94
0

If it's just about minimising the number of calls to memory allocation functions you can created such a jagged array like this:

#include <stdlib.h>
#include <stdio.h>

int ** alloc_jagged_2d_array_of_int(size_t n, size_t m)
{
  int ** result = NULL;
  size_t t = 0;

  t += n * sizeof *result;
  t += n*m * sizeof **result;

  result = calloc(1, t);
  if (NULL != result)
  {
    for (size_t i = 0; i < n; ++i)
    {
      result[i] = ((int*) (result + n)) + i*m;
    }
  }

  return result;
}

Use it like this:

#include <stdlib.h>
#include <stdio.h>

int ** alloc_jagged_2d_array_of_int(size_t, size_t);

int main(void)
{
  int result = EXIT_SUCCESS;

  int ** p = alloc_jagged_2d_array_of_int(2, 3);
  if (NULL == p)
  {
    perror("alloc_jagged_2d_array_of_int() failed");
    result = EXIT_FAILURE;
  }
  else
  {
    for (size_t i = 0; i < 2; ++i)
    {
      for (size_t j = 0; j < 3; ++j)
      {
        p[i][j] = (int) (i*j);
      }
    }
  }

  /* Clean up. */

  free(p);

  return result;
}
alk
  • 69,737
  • 10
  • 105
  • 255