Reputation: 3928
I can have many sensors. Each sensor has an address, current and pressure. Due to the fact I don't know how many sensors there could be, I thought of creating a pointer to structs:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct sensor {
unsigned long long int address;
float current;
unsigned char pressure_units;
};
static struct sensor *sensors;
struct sensor *createSensor(unsigned long long int address, float current, unsigned char pressure_units)
{
struct sensor *temp = malloc(sizeof(struct sensor));
// (*temp).address
temp->address = address;
temp->current = current;
temp->pressure_units = pressure_units;
return temp;
}
void checkSerialHart(int sensorId)
{
sensors = createSensor(10000*sensorId,sensorId+3.0,sensorId);
}
int main(int argc, char *argv[])
{
int i, j;
for(i=0,j=0;i<3;i++)
{
// test case where sensor n doesn't respond
if(i != 1)
{
checkSerialHart(j);
++j;
++sensors;
}
}
printf("address: %llu current: %f pressure: %c\n", sensors[0].address, sensors[0].current, sensors[0].pressure_units);
printf("address: %llu current: %f pressure: %c\n", sensors[1].address, sensors[1].current, sensors[1].pressure_units);
}
I am having trouble keeping a pointer to structs where I can move through the pointer to get values of different sensors. The above prints this:
address: 580340276002816 current: 0.000000 pressure:
address: 0 current: 0.000000 pressure:
But I expected this:
address:0,current:3.000000,pressure_units:0
address:20000,current:5.000000,pressure_units:2
What may I be doing wrong?
Upvotes: 0
Views: 84
Reputation: 15121
Your checkSerialHart()
will overwrite sensors
every time you call it.
Here is one way (not the best) to achieve your goal:
static struct sensor **sensors;
static int sensors_count = 0;
...
void checkSerialHart(int sensorId)
{
sensors = realloc(sensors, (sensors_count+1)*sizeof(*sensors));
if (sensors == NULL)
exit(EXIT_FAILURE);
sensors[sensors_count] = createSensor(10000*sensorId,sensorId+3.0,sensorId);
sensors_count++;
}
...
for(i=0,j=0;i<3;i++)
{
// test case where sensor n doesn't respond
if(i != 1)
{
checkSerialHart(j);
++j;
}
}
for (i = 0; i < sensors_count; i++)
printf("address: %llu current: %f pressure: %c\n",
sensors[i]->address, sensors[i]->current, sensors[i]->pressure_units);
Upvotes: 2
Reputation: 141554
Currently, your
static struct sensor *sensors;
points to a single sensor. When you increment it, you no longer point at a valid sensor, causing undefined behaviour when you later deference.
You have to choose between one of two fundamentally different designs:
(As I write, the other solution mixes up these two options, it won't work as posted).
If you go with option (2) then the only modification you need to make is:
static struct sensor *sensors[MAX_SENSORS];
static size_t num_sensors = 0;
Then you can do sensors[num_sensors++] = createSensor(....
You should avoid doing ++sensors
, and instead either use an index or another pointer if you want to iterate over the sensors. You could also dynamically allocate sensors
instead of having a fixed maximum.
For option (1) you would need to re-design the createSensor
function. It can no longer return a pointer to a new Sensor, nor malloc
memory for a single sensor. Instead, you have to increase the size of your dynamically-allocated sensor array, and then create the new sensor in the space you just allocated.
In either case I would suggest having separate functions for "growing" your allocated storage, than for initializing a new sensor. That will help keep your code clear and easy to maintain.
Upvotes: 0
Reputation: 5731
Your following line is causing the problem:
++sensors;
"sensors" is the global static variable which should be store the base pointer of your array. But inside your for loop, it gets incremented and starts pointing to next(some memory). Hence while printing, it does starts pointing to base address which you wanted to achieve from this program.
Upvotes: 1