0

I want to directly assign values to a 2d array of pointers for which the memory is allocated dynamically. But the compiler shows 2 warning and 1 error.

2 Warnings on line 11 and 12: int differs in level of indirection from int*.

error on line 13: Syntax error : '{'

Here is my code:

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

int main()
{
    int r , c, rc;
    int* pmat1[3][3], pmat2[3][3], pmat3[3][3];

    *pmat1[3] = (int*)calloc(3,sizeof(int));
    *pmat2[3] = (int*)calloc(3,sizeof(int));
    *pmat3[3] = (int*)calloc(3,sizeof(int));

    *pmat1[3][3] = { {1,1,1}, {0,0,0}, {2,2,2} };
    return 0;
}

What error am I making here?

Martin G
  • 17,357
  • 9
  • 82
  • 98
Kiran C K
  • 61
  • 7
  • Please do not cast malloc – Sourav Ghosh Sep 23 '15 at 09:25
  • 1
    In your code `pmat2` and `pmat3` are 2d integer arrays. Probably you want to declare them in this way: `int* pmat1[3][3], *pmat2[3][3], *pmat3[3][3]`. –  Sep 23 '15 at 09:35
  • Are you casting calloc because you get some warnings in which case you are using wrong compiler or you cast calloc because you don't know that return type of calloc (and its familly) is **void*** ? – Michi Sep 23 '15 at 09:40
  • Do you want a 2D array of pointers to arrays, a pointer to a 2D array, or an array of pointers to 2D arrays? These are all very different things and your code seems to want to combine all of them. – Lundin Sep 23 '15 at 09:44
  • `int* x, y, z;` is equivalent to `int* x; int y; int z;`. – molbdnilo Sep 23 '15 at 09:45
  • Seriously people, there's not a single line of correct code here. Casting the result of malloc is the very least of his concerns. Take the malloc cast crusade somewhere else, it is not helpful. – Lundin Sep 23 '15 at 09:46
  • @lundin: I have declared a 2d array of pointers, not a pointer to 2d arrays – Kiran C K Sep 23 '15 at 09:47
  • @KiranCK The declaration is indeed a 2D array of pointers. The calloc allocates an array of data but incorrectly tries to store that in an array of pointers. And after that, you try to initialize the contents of one array item to an array of data, by using an initializer list in runtime... So the actual purpose of the code is not crystal clear – Lundin Sep 23 '15 at 10:04

4 Answers4

1

You have many problems with that code. The first is that only pmat1 is an array of arrays of pointers to int, the others (pmat2 and pmat3) are only arrays of arrays of int (i.e. not pointers).

The second problem is the initialization, you simply can't assign like that, you have to initialize each field separately.

Thirdly, *pmat1[3] doesn't do what you probably expect it to do, besides it's out of bounds, as array indexes start from zero.


If we are going down to a more basic level, if what you want is an array of three arrays of three integers, then you are doing it completely wrong, then it's just enough with

int pmat1[3][3];

The above will cause the compiler to allocate space for a total of nine (3 * 3) int. No need for any dynamic allocation.

You could then initialize it like

pmat1[0][0] = pmat1[0][1] = pmat1[0][2] = 1;
pmat1[1][0] = pmat1[1][1] = pmat1[1][2] = 0;
pmat1[2][0] = pmat1[2][1] = pmat1[2][2] = 2;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

I want to directly assign values to a 2d array of pointers for which the memory is allocated dynamically.

You can't do this. For example:

int *p = malloc(sizeof(*p) * 3);
*p = {1, 2, 3};

is completely wrong. You're assigning {1, 2, 3}, an array of type int[3], to *p, an int. If you've to, do it one by one:

int a[] = {1, 2, 3};
for (size_t i = 0u; i < 3u; ++i)
    p[i] = a[i];

The only time you can do a direct assignment is in an automatic array initialization, such as the a in the above snippet, where the unnamed array {1, 2, 3} is , conceptually, copied to the elements of a.

As Joachim noted, make sure you stay within bounds. [0, n − 1] is the range allowed to be dereferenced for an array of size n. Hence a[3] = 4; is illegal, as a is of size 3, although it'll happily compile, you're treading on UB land.

In C's syntax for pointer declaration, the * operator is associated to the identifier and not the type. In int* a, b;, although * is written next to int, the type is still int and not int*. Only a is of type int* and b is still an int.

Community
  • 1
  • 1
legends2k
  • 31,634
  • 25
  • 118
  • 222
0

Can you please look below code, this code show how pointer array stores values of integer type,

#include <stdio.h>

const int MAX = 3;

int main ()
{
   int  var[] = {10, 100, 200};
   int i, *ptr[MAX];

   for ( i = 0; i < MAX; i++)
   {
      ptr[i] = &var[i]; /* assign the address of integer. */
   }
   for ( i = 0; i < MAX; i++)
   {
      printf("Value of var[%d] = %d\n", i, *ptr[i] );
   }
   return 0;
}
Sanjay Bhardwaj
  • 412
  • 2
  • 10
  • so, what you say is that I can only point to an array for values and cannot directly assign literals to the dynamic pointer – Kiran C K Sep 23 '15 at 09:52
  • as per pointer definition : pointer can store address of another variable. – Sanjay Bhardwaj Sep 23 '15 at 09:57
  • Here, i'm just trying to say is that if you want to take advantage of pointers then you should store only address of another variable. And if you want to store simple values then you should take simple array of int. – Sanjay Bhardwaj Sep 23 '15 at 10:22
0

And, below code shows how pointer array stores string type values,

#include <stdio.h>

const int MAX = 4;

int main ()
{
   char *names[] = {
                   "Zara Ali",
                   "Hina Ali",
                   "Nuha Ali",
                   "Sara Ali",
   };
   int i = 0;

   for ( i = 0; i < MAX; i++)
   {
      printf("Value of names[%d] = %s\n", i, names[i] );
   }
   return 0;
}
Sanjay Bhardwaj
  • 412
  • 2
  • 10