free() in char dynamic stack does not work - C

Asked

Viewed 169 times

0

Hello,

I’m having trouble trying to release dynamically allocated memory. For small string there is time that works, but for large string the program tops. There’s a time when a 3-character or 4-character string works, there’s a time when.

int main()
{
    TPilha* p;
    char str[10];

    scanf("%s",&str);

    p = cria_pilha(10);

    empilha(p,str);
    printf("\n\n");
    desempilha(p);

    libera_pilha(p,0);
    libera_pilha(p,1);
    libera_pilha(p,2);
    libera_pilha(p,3);
    libera_pilha(p,4);
    libera_pilha(p,5);
    libera_pilha(p,6);
    libera_pilha(p,7);
    libera_pilha(p,8);
    libera_pilha(p,9);
    libera_pilha(p,10);

    return 0;
}

At the time of releasing the memory I went position by vector position and was giving free(). I did it to try to understand the mistake.

The problem starts when I try to type something like filipi, and sometimes even something with three characters, like fhg, but strangely it works with fil or fili.

My structure is this:

typedef struct pilha TPilha;
struct pilha{
    int topo;
    int prox;
    int tamanho;
    char** PILHA;
};

I initialize her like this:

TPilha*cria_pilha(int tam){

    TPilha* aux = (TPilha*)malloc(sizeof(TPilha));
    aux->PILHA = (char**)malloc(sizeof(char*) * tam);
    aux->topo = NULL;
    aux->prox = 0;
    aux->tamanho = tam;

    return aux;
}

To stack I do so:

void empilha(TPilha* aux,char* num){

    if(pilha_vazia(aux)!=2){// Só posso empilhar se não for 2, 2 = pilha cheia

        for (int i=0; i<strlen(num); i++){
            aux->PILHA[aux->prox] = num[i];
            aux->topo = aux->prox;
            aux->prox++;
            printf("PILHA[%d] = %c EMPILHADO\n",aux->prox-1,aux->PILHA[aux->topo]);
        }
    }
}

To unstack I do:

int desempilha(TPilha* aux){
    for (int i=aux->prox; i!=0; i++){
        if(pilha_vazia(aux)==1){
            printf("Pilha vazia\n");
            return 0;
        }
        printf("PILHA[%d] = %c REMOVIDO\n",aux->topo,aux->PILHA[aux->topo]);
        aux->prox = aux->topo;
        aux->topo--;
    }
}

To check if the stack is empty:

int pilha_vazia(TPilha* aux){
    if(aux->prox == 0){
        return 1;
    }
    else if(aux->prox == aux->tamanho){
        printf("Pilha cheia\n");
        return 2; 
    }
    return 0;
}

And to release I do:

void libera_pilha(TPilha* aux,int i){
   //for (int i=0; i<aux->tamanho; i++){
        //free(aux->PILHA[i]);
        printf("liberado - %d\n",aux->PILHA[i]);
        free(aux->PILHA[i]);
    //}
    //free(aux->PILHA);
    //free(aux);
}

The idea is to do the free() with the loop, but I removed it to do one by one and understand where the error is happening, but there is a pattern in the error, there is time that works and there is time that does not. What’s going on?

Who cares I left the code in a . rar here.

  • 1

    do not put pictures in questions, always put only text...it is possible that your question is closed because of this

  • I get it, I’m gonna change that. Thank you!

  • 1

    also put the function code "stack" and "pop"

  • Okay, I’ll put it on. I hadn’t put it on because I thought it was going to be too much.

  • 1

    Connects the warnings of your compiler (gcc ... -Wall -Wextra ...) and pay attention to them.

  • @pmg will do it, thank you!

Show 1 more comment

1 answer

1


From the information that is in the question it is possible to see that there is (at least) one thing wrong: in the creation of the pointer vector it is necessary to initialize the pointers, which is not being done:

TPilha* cria_pilha(int tam) {
    TPilha* aux = (TPilha*)malloc(sizeof(TPilha));
    aux->PILHA = (char**)malloc(sizeof(char*) * tam);
    memset(aux->PILHA, 0, sizeof(char*) * tam);        // faltando
    aux->topo = NULL;
    aux->prox = 0;
    aux->tamanho = tam;
    return aux;
}

Note: It is not customary to use uppercase names for variable or type names, only for names defined by #defines.

UPDATE

In the stack function there is also an error

void empilha(TPilha* aux, char* num ) {
  if (pilha_vazia(aux) !=2 ) { // Só posso empilhar se não for 2, 2 = pilha cheia
    for (int i = 0; i < strlen(num); i++) {
      aux->PILHA[aux->prox] = num[i]; // <------- ERRO
      aux->topo = aux->prox;
      aux->prox++;
      printf("PILHA[%d] = %c EMPILHADO\n",aux->prox-1,aux->PILHA[aux->topo]);
    }
  }
}

On the highlighted line there is an assignment of a character to a pointer:

aux->PILHA[aux->prox] = num[i]; // <------- ERRO  

I haven’t analyzed the logic of this command, but most likely there’s something wrong there.

  • Interesting, I added this missing line but still the error persists. This code before was for an integer vector, and even without this initialization it worked normally. Then I adapted it to receive characters and started to make a mistake. Thank you for mentioning this, I will study this memset() function that I did not know until then. On the use of capital letters, in fact, it is not really something used, I will correct this habit of mine. Thank you!

  • I get it, I’ll check this assignment and come back with a.

  • UPDATE: This code was with several errors, one of them was mentioned by @zentrunix, and from the mentioned error I was noticing others, so I will declare his response as solution. The main error of the code is that I was creating a pointer vector of the "char pointer" type, then I was assigning a char to a pointer, and then I was trying to free up memory from spaces that didn’t exist, and it was a mess. The correct one was to make a dynamic allocation of a char vector, and insert one character at a time, and then give free() in STACK, that’s all.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.