Pointer to an array of structures and memory access

A link is a pointer to a node

 typedef struct node * link; 

In main (), I have the following code (config-> m is just some integer):

 // array of pointers to structs link heads[config->m]; // make memory for head nodes for(i = 0; i < config->m; i++) heads[i] = malloc(sizeof(struct node)); 

The code is working (which is great). But is there a way to allocate config->m parts of memory without a loop? I tried

 link heads[config->m]; heads = malloc(sizeof(struct node) * config->m); 

but my friendly neighborhood compiler tells me incompatible types in assignment

I know I can use

 struct node heads[config->m]; 

But I want to do this with pointers.

And as always, someone will ask me if this is part of the homework, and the answer is yes (sort of). But this particular piece of code has nothing to do with the actual purpose; this is for my own enlightenment. But thanks for asking: |

+4
source share
2 answers

No, you need a loop. Your head array is essentially a two-dimensional array. You need at least two distributions. The first is an array of pointers:

 link * heads = (link*)malloc (config->m * sizeof (link)); 

The second is the memory in which each member of the head array points to:

 link buf = (link)malloc(sizeof(struct node) * config->m); for(i = 0; i < config->m; i++) heads[i] = &buf[i]; 

Then deselect:

 free(heads); free(buf); 
+3
source
 link heads[config->m]; link buffer = malloc(sizeof(struct node) * config->m); for(i = 0; i < config->m; i++) heads[i] = &buffer[i]; .... free(buffer); 

Editor: In fact, you do not need heads . First, let me get rid of link , as (see comments in Cannonade's answer) this just confuses the problem.

Suppose a node structure is a node in an intrusively linked list and looks like this:

  struct node { int val; int filler[10]; // this is pure filler, to make node big struct node* next; }; 

Now add our include and config-> m:

  #include <stdio.h> #include <stdlib.h> // your config->m const int m = 10 ; 

And in main () we print the size of the node:

  int main() { printf( "sizeof( struct node ) = %i\n", sizeof( struct node) ); 

Now we declare a pointer to node:

  // na is a node pointer struct node* na; 

And malloc up m nodes. malloc returns the address of the array, which is also the address of the first node in the array. We set na to the malloc address returned:

  na = malloc(sizeof(struct node) * m); 

Now we will use na, a pointer, as if it were an array. This works because C defines array[offset] as *(array + offset * sizeof(element))

  int i; // we give the first node a val of zero na[0].val = 0; // and a null next pointer na[0].next = 0 ; 

Now we look at the rest of the array and set each node next to the PREVIOUS node in the array:

  for(i = 1; i < m; i++) { na[i].val = i ; // na[ offset ] is *(na + offset) // we don't want to dereference, // we want the address, so we use the // address-of operator ("&") na[i].next = &na[ i - 1 ]; } 

Our head is the LAST node in the na[ m - 1] array. Each next in the list is the previous node in the array. Again, we use the address operator if we want a pointer, and not what is indicated:

  struct node* current = &na[ m - 1 ]; 

We will print the address of each node. It should be the address of its pointer next node + sizeof( struct node) , because each node is a node after (in an array) its next in the list (a list is an "inverse" array).

We pass it char * to get the result in bytes. If we don't pronounce, we get the result in units of truct node* (which should always be 1).

  while( current ) { printf( "val %i, address of current %p, ", current->val, current) ; printf( " address of current->next %p, ", current->next ) ; if( current->next ) { printf( " distance from next: "); printf( "in bytes %i, ", ( (char*) current) - (char*) current->next ) ; printf( " in struct nodes %i", current - current->next ) ; } printf( "\n" ); current = current->next; } return 0; } 

On my system, this gives this result:

  sizeof( struct node ) = 48 val 9, address of current 0x804a1b8, address of current->next 0x804a188, distance from next: in bytes 48, in struct nodes 1 val 8, address of current 0x804a188, address of current->next 0x804a158, distance from next: in bytes 48, in struct nodes 1 val 7, address of current 0x804a158, address of current->next 0x804a128, distance from next: in bytes 48, in struct nodes 1 val 6, address of current 0x804a128, address of current->next 0x804a0f8, distance from next: in bytes 48, in struct nodes 1 val 5, address of current 0x804a0f8, address of current->next 0x804a0c8, distance from next: in bytes 48, in struct nodes 1 val 4, address of current 0x804a0c8, address of current->next 0x804a098, distance from next: in bytes 48, in struct nodes 1 val 3, address of current 0x804a098, address of current->next 0x804a068, distance from next: in bytes 48, in struct nodes 1 val 2, address of current 0x804a068, address of current->next 0x804a038, distance from next: in bytes 48, in struct nodes 1 val 1, address of current 0x804a038, address of current->next 0x804a008, distance from next: in bytes 48, in struct nodes 1 val 0, address of current 0x804a008, address of current->next (nil), 
+1
source

All Articles