Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing the -1 element of an array in c

I have an array of structs, which is dynamically allocated. A pointer to this array is passed around to other functions.

struct body{
    char* name; 
    double mass; 
    // ... some more stuff
    };

 body *bodies = malloc(Number_of_bodies*sizeof(body));

I need to know the size of the array, so I'm storing the size in one of the structs, which is in the 0th element of the array (the first struct).

bodies[0].mass = (double)Number_of_bodies;

I then return from the function a pointer to the 1st element of the array i.e bodies[1]

  return (bodies+1); 

Now, when I use this pointer in other functions, the data should start at the 0th element.

  body *new_bodies = (bodies+1);     //Just trying to show what happens effectively when i pass to another function
  new_bodies[0] = *(bodies+1);       //I Think

If I want to see the initial struct, which was at bodies[0], does that mean in other functions I have to access new_bodies[-1] ?

Is this something I can do? How can I access the initial struct?

like image 624
Rohan Avatar asked Nov 12 '14 16:11

Rohan


People also ask

How do you access one element of an array?

We can access elements of an array using the index operator [] . All you need do in order to access a particular element is to call the array you created. Beside the array is the index [] operator, which will have the value of the particular element's index position from a given array.

How will you access the elements of an array in C?

Array elements can be accessed using the position of the element in the array.


1 Answers

Yes, you can use new_bodies[-1] to access the initial element of the array. This is perfectly legal.

The reason behind this is pointer arithmetic: square brackets is another way of writing +, so when you write new_bodies[-1] it is the same as *(new_bodies-1).

Since new_bodies has been obtained as bodies+1, new_bodies-1 is (bodies+1)-1, or bodies, making new_bodies[-1] identical to bodies[0].

Note: It looks like you are trying to shoehorn the number of elements into the initial element of the array of your structs, re-purposing the mass field for it. This will work, but it is suboptimal, both in terms of memory allocation (a pointer name remains unused) but most importantly in terms of readability. You would be a lot better off using a flexible array member in a struct that stores the number of entries explicitly:

struct body {
    char* name; 
    double mass; 
    // ... some more stuff
};
struct bodies {
    size_t count;
    body bodies[]; // <<== Flexible array member
};
...
bodies *bb = malloc(sizeof(bodies)+Number_of_bodies*sizeof(body));
bb->count = Number_of_bodies;

Here is a link to another Q&A with an example of working with flexible array members.

like image 158
Sergey Kalinichenko Avatar answered Oct 16 '22 12:10

Sergey Kalinichenko