below_avg_st
below_avg_st

Reputation: 197

Memory leak in malloced pointers?

I am getting a two instances of memory leaks that I can't seem to solve. The first instance occurs from char *temp = (char*)malloc(sizeof(char*));, I use this variable at the beginning of a if statement and make sure to free it at the end, but I'm still getting a leak. The second occurs from s = create(); and s = (Stack*)malloc(sizeof(Stack));.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
    char **data;
    int top;
    int size;
}Stack;
typedef enum { FALSE, TRUE } bool;
Stack* create(){
    Stack *s;
    s = (Stack*)malloc(sizeof(Stack));
    s->top = -1;
    s->size = 10;
    s->data = (char**)malloc(s->size*sizeof(char*));
    return s;
}
void deleteStack(Stack* ps){
    if(ps == NULL){
        printf("No memory allocated in Stack.\n");
    }
    while(ps->top >= 0){
        free(ps->data[ps->top]);
        ps->top--;
    }
    free(ps->data);
}
bool full( Stack s){
    if(s.top == s.size-1)
        return TRUE;
    return FALSE;
}
void push( Stack* ps, char* str){
    if(full(*ps)){
        int tempsize = ps->size;
        ps->size += 10;
        ps->data = realloc(ps->data, ps->size * sizeof(char*));
    //  char **temp = realloc(ps->data, ps->size*sizeof(char*));
    //  if(temp == NULL){
    //      perror("realloc");
    //      printf("Error! memory not allocated.\n");
    //      exit(-1);
    //  }
    //  ps->data = temp;
        printf("Stack capacity has grown from %d elements to %d elements\n", tempsize, ps->size);   
    }
    ps->data[++ps->top] = strdup(str);
}
bool empty( Stack s){
    if(s.top == -1)
        return TRUE;
    return FALSE;
}
char* pop( Stack* ps){
    if(empty(*ps))
        return NULL;
    return ps->data[ps->top--];
}
int main(int argc, char *argv[]){
    printf("Assignment 2 Problem 1 by Jasmine Ramirez\n\n");
    FILE *input = fopen("data_a2.txt", "r");
    if(input == NULL){
        perror("fopen");
        printf("File %s not found.\n", "data_a2.txt");
        exit(EXIT_FAILURE);
    }
    Stack *s;
    s = create();                <---16 bytes in 1 block definitely lost
    char str[255];
    char *temp = (char*)malloc(sizeof(char));   <---1 bytes in 1 block definitely lost
    int i = 0;
    while(fscanf(input, "%s\n", str) == 1){
        if(strcmp(str, "pop") == 0){
            temp = pop(s);
            i--;
            printf("# of elements after popping: %d\tstring popped: %s\n", i, temp);
            free(temp);
        }
        else{
            push(s, str);
            i++;    
        }
    }
    deleteStack(s);
    fclose(input);
    return 0;
}

I can't figure out the reason for the 1 byte lost in temp and s is supposed to be taken care of by deleteStack().

Upvotes: 1

Views: 144

Answers (2)

Pras
Pras

Reputation: 4044

At this statement

temp = pop(s);

Pointer to earlier malloced memory is lost so it is leaked.

In deleteStack, you have not freed ps, so that's a leak too, as memory allocated to Stack *s; in create never gets released.

Upvotes: 3

pat
pat

Reputation: 12749

You should free(ps) at the end of deleteStack.

The temp pointer to the single mallocd char is overwritten with the result from pop, so it is leaked. Why do you need to allocate that single char? Just initialize it to NULL, or leave it uninitialized.

In production code, you should always test the value returned from malloc or realloc, and should never assign the result of realloc over your only pointer to the memory you are trying to reallocate. If it reurns NULL, you just leaked it.

Also, in deleteStack, you test for NULL, but then continue to dereference the pointer anyway.

Upvotes: 3

Related Questions