0

Here I attempt to create a matrix, by assigning arrays to a pointer reference:

bb_ANN(int num_Weights, int num_Layers, int num_Nodes, double * inputs){

//create an array that will hold pointers
struct ANN_Node *layer[num_Layers];
//create an array of nodes
struct ANN_Node **arr = malloc(sizeof(struct ANN_Node **) *num_Layers);
//initialize Nodes
for(int i=0;i<num_Layers;i++)
{       
    // layer heads
    layer[i] = ANN_Init_Node(num_Weights); 
    for(int j=0; j<num_Nodes;j++)
    //push nodes into each layer head
    { push_ANN_Node(&layer[i],num_Weights); }
    // converting each list into an array, then each embedding into arr[] 
     arr[i] = arrayOfList(layer[i]); 
}


    printf("f(x):%f ", arr[0][1].weights[0]);
////////////

This is the arrayOfList definition :

struct ANN_Node *arrayOfList(struct ANN_Node *listP){
int i = lengthOfList(listP) ; //make i the length of the list
struct ANN_Node **ptr=  malloc(sizeof(struct ANN_Node **) *i);
for(i=0;listP != NULL;listP=listP->next,i++)
{ ptr[i] = listP; }
return ptr;
    }

Now what I am attempting to do, is to make a sort of matrix of 'ANN_Nodes' :

-->[ 0 0 0 ]
-->[ 0 0 0 ]
-->[ 0 0 0 ]

whereby, I create a loop which goes through each layer and inserts an array that my arrayOfList function would return.

Now there's this resulting thing: arr[0][0].weights[0] and this is fine. So is this arr[1][0].weights[0] and this arr[2][0].weights[0] etcetera.

But I have failed to actually create something two dimensional : arr[0][1].weights[0] this is a failure and a segfault.

Does what I am attempting to do make sense, is it feasible, and how might I actually achieve a two dimensional array structure so that I can carry on with my purposes ?

PS. I have checked out multidimensional arrays already but I think my case is a bit different from the majority of examples and tutorials I find on the internet, I am trying to sort of inject a returned array into and array of arrays if that makes sense...

timi95
  • 368
  • 6
  • 23
  • `sizeof(struct ANN_Node *)` gives you the size of a pointer (which is architecture dependant). If you want the size of the struct, use `sizeof(struct ANN_Node)` – Umaiki Apr 27 '18 at 11:53
  • In C you [don't have to cast the result of `malloc`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Some programmer dude Apr 27 '18 at 13:09
  • @Someprogrammerdude, I suppose so. I've read some arguments on this site however, both for and against the casting thing, the way I understood it, it seemed the pro's for casting, is that its more generalisable in some way that prevents some unique errors. I took it as 'safer' and just kept doing it in the hope that it's good form. – timi95 Apr 27 '18 at 13:15
  • Not casting should not create any problems, but casting *will* create problems if you forget to include the `` header file. – Some programmer dude Apr 27 '18 at 13:19
  • Is it even recommended to write a C program without including ? @Someprogrammerdude – timi95 Apr 27 '18 at 13:31

1 Answers1

1

If your arrayOfList function you create an "array" of pointers, and make ptr point to that memory.

Then you do return *ptr; which is equal to return ptr[0];. That is, you return a single pointer to a single element. The rest of the "array" will be lost.

If you want a dynamic "2d array" of pointers in C you need to become a three-star programmer, as it will be (in your case) of type struct ANN_Node ***.

Then arrayOfList should return struct ANN_Node **, i.e. ptr (instead of *ptr).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • wouldn't it be better to allocate a big block once(as the size is known at allocation) and then just access this correctly insteast of using a pointer to pointer to pointer construct? – Kami Kaze Apr 27 '18 at 12:00
  • @KamiKaze It's of course one solution. It kind of depends on use-case and other requirements and limitations (a single allocation of a big block might not be possible for large amounts of data). – Some programmer dude Apr 27 '18 at 12:03
  • I changed the array of List function to this : `struct ANN_Node **arrayOfList(struct ANN_Node *listP) { int i = lengthOfList(listP) ; //make i the length of the list struct ANN_Node **ptr= (struct ANN_Node **) malloc(sizeof(struct ANN_Node) *i); for(i=0;listP != NULL;listP=listP->next,i++) { ptr[i] = listP; } return ptr; }` But I still seem to get segfault. – timi95 Apr 27 '18 at 13:07
  • @timi95 Now you're allocating the wrong size, probably to much. And did you remember to change the `bb_ANN` function accordingly? – Some programmer dude Apr 27 '18 at 13:09
  • @Someprogrammerdude yah, some one commented this : "sizeof(struct ANN_Node *) gives you the size of a pointer (which is architecture dependant). If you want the size of the struct, use sizeof(struct ANN_Node)" . So I changed it, I will revert back to what it was. What do I need to change with the assignment in bb_ANN ? – timi95 Apr 27 '18 at 13:18
  • This was the solution !! : ` //create an array of nodes struct ANN_Node ***arr = malloc(sizeof(struct ANN_Node **) *num_Layers);` . So now I am assigning an appropriate structure to 'arr' and my warnings are gone now. PS. Thank you, if you have anything to add about how I might avoid situations like this in future, I'd be very keen for such advice. @Someprogrammerdude – timi95 Apr 27 '18 at 13:46