2

I've been trying to debug this for hours.


I have a struct for a scheduler.

typedef struct rr_scheduler {
    unsigned int time_q;
    unsigned int avg_wait;
    unsigned int avg_turnaround;
    unsigned int processes_served;
    unsigned int t;
    unsigned int next_dispatch_t;
    Process* cp;
    LinkedList* queue;
    LinkedList* done_list;
} rr_scheduler;

It's being initialised as so:

rr_scheduler* new_rr_scheduler(unsigned int time_q) {
    rr_scheduler* rr = NULL;

    rr = (rr_scheduler*)malloc(sizeof rr);

    rr->time_q = time_q;
    rr->queue = newLinkedList();
    rr->done_list = newLinkedList();
    rr->avg_wait = 0;
    rr->avg_turnaround = 0;
    rr->processes_served = 0;
    rr->t = 0;
    rr->next_dispatch_t = 0;
    rr->cp = NULL;

    return rr;
}

Here's the linkedList initialisation function. (Yes, I know I don't need to set values to null if I'm using calloc)

LinkedList* newLinkedList() {
    LinkedList* newList = (LinkedList*)calloc(1, sizeof (LinkedList));
    newList->head = NULL;
    newList->tail = NULL;
    newList->current = NULL;
    newList->length = 0;
    return newList;
}

After pulling my hair out for ages, I noticed that two unrelated variables changed simultaneously. Turns out, scheduler->cp and scheduler->queue->tail seem to share a memory address.

Picture of same address phenomenon

Here, s is an rr_scheduler pointer.

Any possible reasons for this would be greatly appreciated.

scradam
  • 23
  • 4
  • Initializing stuff to NULL/0 is not needed after `calloc()` - but maybe you added that only now for clarity. – Yirkha May 13 '14 at 15:42

1 Answers1

4
sizeof rr

is the size of the pointer. But you need to allocate enough memory for the struct. Use

sizeof *rr

or

sizeof(rr_scheduler)

to do that.

As it stands in your program, you don't allocate enough memory for the struct and so write beyond the end of the block, thus corrupting the heap.

It also seems odd to initialise rr to NULL and then immediately assign to it. I would write that as

rr_scheduler* rr = malloc(sizeof *rr);
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • I would do sizeof (struct rr_scheduler) but either way he isn't allocating enough memory. – ojblass May 13 '14 at 15:45
  • 2
    @ojblass `sizeof *rr` is superior because you don't have to duplicate the type name, leading to more maintainable and clear code. – Filipe Gonçalves May 13 '14 at 15:46
  • @FilipeGonçalves That is debateable. Instead of duplicating the type name, you duplicate the variable name. – David Heffernan May 13 '14 at 15:48
  • Sure, but duplicating the variable name is not as bad as doing it for the type name. Have a look at http://stackoverflow.com/questions/373252/c-sizeof-with-a-type-or-variable – Filipe Gonçalves May 13 '14 at 15:56
  • @FilipeGonçalves OK, maybe you have a point. But one does at least need to think about it a little. Which clearly I did not do enough of! ;-) – David Heffernan May 13 '14 at 15:57
  • 1
    If you use the variable name, you can change its type without breaking the `malloc()` – JeremyP May 13 '14 at 16:04
  • Great response, I had a few other instances of this same issue, too! Residual null initialising code has been cleaned up and everything is working great. – scradam May 13 '14 at 16:10