tags:

views:

222

answers:

2

Ok guys, just a quick question hopefully someone can find my mistake quickly, but I just can't see it at the moment

Here is my struct:

typedef struct {
    Car *buffer[CAR_PARK_SIZE];       
    char *arrival_time[CAR_PARK_SIZE]; 
    int  keep_running;            
    int  size;            
} CarPark;

typedef struct {
    Car *buffer[MAX_QUEUE_SIZE];
    char *arrival_time[MAX_QUEUE_SIZE];
    int keep_running;
    int size;
    int index;
    } CarQueue;

typedef struct {
    char str[3];
    int id;
} Car;

I'll try to talk this out and hopefully i've provided enough information for someone to find out where the problem may lie, the problem is to do with the pointer in the CarQueue buffer, which is meant to be an array of car pointers. When my code runs, it seems to write the same pointer to ever item in the CarQueue buffer, here's the play by play.

_cq = CarQueue, _cp = CarPark

They are both globals

My thread calls these lines to generate a new car struct.

Car c;
c = new_car();
printf("[A] Car Arrived with ID: %s\n", get_car_id(&c));

pthread_mutex_lock(&mutex);
_cq.size++;
_cq.index++;
_cq.buffer[_cq.index] = &c;

pthread_mutex_unlock(&mutex);

This should put the pointer of the new car structure into the the CarQueue buffer.

The next thread than attempts to take the pointer out of that array, and stick it into its own, and then remove it from the old array. CarPark takes the pointer of the car, puts it into it's storage array, and then removes it from CarQueue (or in this case, just increases the index and overrides it later).

pthread_mutex_lock(&mutex);
_cp.buffer[_cp.size] = _cq.buffer[_cq.index]; //should take the pointer and put it into its own
printf("[C] Car Parked -> %s\n", get_car_id(_cp.buffer[_cp.size])); //gets the right information
_cp.size++;
pthread_mutex_unlock(&mutex);

I think the problem lies around where the comment in the code is, but I am not certain. Eventually if I print out the array in CarPark, all it's items seem to be the exact same. Am I passing a wrong pointer to a pointer somewhere accidentally?

if I traverse through the CarPark array and print it out like the following

printf("| element %d is  %s with pointer %d |\n", j, get_car_id(_cp.buffer[j]), _cp.buffer[j]);

They all appear to be the exact same item, same name and pointer.

+3  A: 

problem is here:

Car c;
c = new_car();
get_car_id(&c);

you're taking pointer at object on stack, so it is deleted/overwritten every time, so the pointers can be the same.

Car *c;
c = new_car();

and new_car should return pointer.

EDIT:

new_car should malloc() the new car, (and you need to free() it somewhere, for example when removing from queue).

Consider using array of cars(not array of pointers on cars), and copying the whole item.

Yossarian
does this mean the new_car() method would have to malloc it to stop it being in its stack? Also if the separate thread is pulling the right information out of the queue before putting it into the park (while new cars are still being created and added to queue in the first thread), then at some point still separate pointers. Even if one was nuked, it'd be a null reference, it wouldn't magically point to the other object... right?
bjeanes
A: 

Is the Car in the example allocated on the stack?

Objects shared between threads should be allocated on the heap using malloc.

Will