Andrius Svilys
Andrius Svilys

Reputation: 11

C - Program crash after free()

I have a program that creates a struct named Stack that holds a pointer to an array of ints and an int that shows the size of this array. I have functions to:

  1. Initialize the struct with empty values
  2. Push integers to the array (dynamically allocate more memory and write a value to it)
  3. Pop an int from the array

However, when I try to pop the last element by freeing the memory it occupies, my program crashes.

What am I doing wrong here?

Is my process correct?

I realize the problem is probably that I'm trying to free a segment of memory that has not been allocated dynamically, but I just don't see where the issue is exactly.

#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
struct Stack{
    int *array;
    int size;
};
typedef struct Stack Stack;
void initStack(Stack *stack);
void push(Stack *stack, int value);
int pop(Stack *stack);

int main()
{
    Stack firstStack;
    initStack(&firstStack);
    push(&firstStack, 1222);
    pop(&firstStack);
    push(&firstStack, 555);
    for(int i = 0; i < firstStack.size; ++i){
        printf("#%d: %d (%p) ", i , firstStack.array[i], &firstStack.array[i]);
    }
    return 0;
}

void initStack(Stack *stack){
    stack->array = NULL;
    stack->size = 0;
}
void push(Stack *stack, int value){
    int size = stack->size;
    int newSize = size + 1;
    stack->array = realloc(stack->array, newSize * sizeof(int));
    if(stack->array != NULL){
        stack->array[size] = value;
        stack->size = stack->size + 1;
    }
    else{
        printf("MALLOC ERROR");
    }
}
int pop(Stack *stack){
    int lastValue = stack->array[stack->size];
    int lastIndex = (stack->size)-1;
    int* lastAddress = (stack->array)+lastIndex;
    free(lastAddress);
    stack->size = (stack->size) - 1 ;
    printf("memory free\n");
    return lastValue;
}

Upvotes: 1

Views: 372

Answers (2)

John Bode
John Bode

Reputation: 123448

This is a problem:

int* lastAddress = (stack->array)+lastIndex;
free(lastAddress);

The argument to free must be an address value returned from malloc, calloc, or realloc - you cannot free memory at an arbitrary address, even within a dynamically allocated block.

Upvotes: 0

MikeCAT
MikeCAT

Reputation: 75062

    int* lastAddress = (stack->array)+lastIndex;
    free(lastAddress);

is wrong because lastAddress may not be an address allocated via malloc() family by adding lastIndex.

Remove the line

    free(lastAddress);

If you want the system to change tha allocated size, you should change the line to

    stack->array = realloc(stack->array, ((stack->size) - 1) * sizeof(int));

Upvotes: 2

Related Questions