-2

I'm a beginner in C. I currently have a task to create a program having multiple queues. How should i correct this? From my understanding, is supposed to clear all of the queues that where created. As currently i think i have memory leaks.

#include <stdio.h> //printf etc
#include <stdlib.h> //malloc calloc realloc free
#include <stdint.h>

/* number of message queues */
#define MSGQS_LEN 5

/* number of nodes in the message queue */
#define CAPACITY 5

typedef struct _node {
    const char* message;
    struct _node* next;
} node_t;

typedef struct {
    char qName;
    node_t *front, *rear;
} msg_queue_t;


typedef struct {
    msg_queue_t **queues;
} MsgQs_t;
  • This thread might help. https://stackoverflow.com/questions/1957099/how-do-free-and-malloc-work-in-c. Basically you should `free` the memory you allocate with `malloc` (and variants). – Mathieu Borderé Dec 16 '19 at 11:54
  • *"As currently i think i have memory leaks."* - Why? – klutt Dec 16 '19 at 11:57
  • 1
    Please don't make more work for others by vandalizing your posts. By posting on the Stack Exchange (SE) network, you've granted a non-revocable right, under a [CC BY-SA license](//creativecommons.org/licenses/by-sa/4.0), for SE to distribute the content (i.e. regardless of your future choices). By SE policy, the non-vandalized version is distributed. Thus, any vandalism will be reverted. Please see: [How does deleting work? …](//meta.stackexchange.com/q/5221). If permitted to delete, there's a "delete" button below the post, on the left, but it's only in browsers, not the mobile app. – Makyen Dec 22 '19 at 23:19

2 Answers2

1

Your code has several problems.

if(msg_queues < 0)
        exit(EXIT_FAILURE);

This test is not correct, msg_queues will be NULL if malloc failed for some reason, the test should read.

if(msg_queues == NULL)
        exit(EXIT_FAILURE);
/* Relinquishes all resources currently held by a MsgQs_t.
   The pointer to the MsgQs_t in question is set to NULL. */
MsgQs_t* unloadMsgQs(){
    MsgQs_t *msg_queues;
    msg_queues = NULL;

    return(msg_queues);
}

You allocate a variable on the stack, initialize it to NULL and return NULL from this function.

What you actually want to do is pass a MsqQs_t* to unloadMsgQs and use this pointer as an argument to free, something like this

void unloadMsgQs(MsgQs_t *msg_q) {
    if(msg_q) {
        free(msg_q);
    }
}

If you want to set the msg_q pointer to NULL so that it can't be reused anymore, you should probably do something like.

void unloadMsgQs(MsgQs_t **msg_q) {
    if(msg_q && *msg_q) {
        free(*msg_q);
        *msg_q = NULL;
    }
}

From what I see, my advice would be to read some more books / tutorials on programming with C and pointers in general, because it seems you don't quite grasp the basics yet (which is nothing to be ashamed of of course!)

Mathieu Borderé
  • 4,357
  • 2
  • 16
  • 24
0

You have to call free with the pointer value returned from malloc. For this you have to pass the pointer to unloadMsgQs as an argument.

If this function is supposed to set the pointer to NULL in the caller, you have to pass the address of the pointer.

Note that malloc's return value to indicate an error is NULL not a value < 0.

/* Returns a pointer to MsgQs_t structure and through which multiple message queues can be subsequently created.
   Each individual message queue is to be identified by a unique identifier. */
MsgQs_t* initializeMsgQs(){
    MsgQs_t* msg_queues;
    msg_queues = malloc(sizeof(MsgQs_t));

    if(msg_queues == NULL)
        exit(EXIT_FAILURE);

    return(msg_queues);
}


/* Relinquishes all resources currently held by a MsgQs_t.
   The pointer to the MsgQs_t in question is set to NULL. */
void unloadMsgQs(MsgQs_t **msg_queues){

    if(msg_queues != NULL)
    {
        free(*msg_queues);
        *msg_queues = NULL;
    }
}

/* sample use in main() */
int main(int argc, char **argv)
{
    MsgQs_t* msg_queues;

    msg_queues = initializeMsgQs();
    /* ... */
    unloadMsgQs(&msg_queues);

    return 0;
}
Bodo
  • 9,287
  • 1
  • 13
  • 29