Search code examples
cwindowsmemory-managementhandlememory-corruption

How to use free on a handle inside a list?-> C -> windows API


I have a list in C that is something like this:

typedef struct _node
{
   int number;
   DWORD threadID;
   HANDLE threadH;
   struct *_node next;
} *node;

And you have somthing like this:

node new_node = malloc(sizeof(node));

As you may have guessed out, this list will store information for threads, including their handlers and Id's. Still I am having trouble when I try to do this:

free(new_node);

Everytime I try to do this I encounter an unexpected error, VS saying that there was a data corruption. I've pinned down as much as possible and I found that the problem resides when I try to use free the handle. I've searched on MSDN how to do this but the only thing I can find is the function that closes the thread (which is not intended here, since I want the thread to run, just deleting it's record from the list).

The question is: how I am supposed to free an handle from the memory? (Considering that this is only a copy of the value of the handle, the active handle is not being deleted).

EDIT: This is the function to insert nodes from the list:

int insereVisitanteLista(node* lista, DWORD threadID, HANDLE threadH, int num_visitante)
{
    node visitanteAnterior;
    node novoVisitante = (node)malloc(sizeof(node));

    if(novoVisitante == NULL)
        return 0;

    novoVisitante->threadID = threadID;
    novoVisitante->threadH = threadH;
    novoVisitante->number = num_visitante;
    novoVisitante->next = NULL;

    if(*lista == NULL)
    {
        *lista = novoVisitante;
        return 1;
    }

    visitanteAnterior = *lista;

    while(visitanteAnterior->next != NULL)
        visitanteAnterior = visitanteAnterior->next;

    visitanteAnterior->next =novoVisitante;
    return 1;
}

And this is the function to delete nodes:

int removeVisitanteLista(node * lista, DWORD threadID)
{
    node visitanteAnterior = NULL, visitanteActual;

    if(*lista == NULL)
        return 0;

    visitanteActual = *lista;

    if((*lista)->threadID == threadID)
    {
        *lista = visitanteActual->next;
        visitanteActual->next = NULL;
        free(visitanteActual);

        return 1;
    }

    while(visitanteActual != NULL && visitanteActual->threadID != threadID)
    {
        visitanteAnterior = visitanteActual;
        visitanteActual = visitanteActual->next;
    }

    if (visitanteActual == NULL)
        return 0;

    visitanteAnterior->next = visitanteActual->next;
    free(visitanteActual);

    return 1;
}

Solution

  • What exactly is a node that you are trying to free? Is this a pointer to a struct _node? If yes, have you allocated it previously? If no, free is not needed, otherwise you have to check if node is not NULL and make sure you do not free it multiple times. It is hard to guess what you are doing and where is an error without a minimal working example reproducing the problem. The only thing I can suggest is to read about memory management in C. This resource might help.

    UPDATE:

    node in your code is a pointer to _node. So sizeof (node) is a size of a pointer, which is either 4 or 8 bytes (depending on architecture). So you allocate 8 bytes, for example, but assume you have a pointer to the structure which is much larger. As a result, you corrupt memory, and behavior of the program becomes undefined. So changing node novoVisitante = (node)malloc(sizeof(node)) to node novoVisitante = (node)malloc(sizeof(_node)) should fix the problem.