Сбой C-программы после free ()

#arrays #c #struct #free #realloc

#массивы #c #структура #Бесплатно #перераспределение

Вопрос:

У меня есть программа, которая создает структуру с именем Stack, которая содержит указатель на массив целых чисел и значение int, которое показывает размер этого массива. У меня есть функции для:

  1. Инициализируйте структуру пустыми значениями
  2. Помещайте целые числа в массив (динамически выделяйте больше памяти и записывайте в нее значение)
  3. Извлеките int из массива

Однако, когда я пытаюсь извлечь последний элемент, освободив занимаемую им память, моя программа выходит из строя.

Что я здесь делаю не так?

Правильно ли мой процесс?

Я понимаю, что проблема, вероятно, в том, что я пытаюсь освободить сегмент памяти, который не был выделен динамически, но я просто не вижу, в чем именно проблема.

 #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(amp;firstStack);
    push(amp;firstStack, 1222);
    pop(amp;firstStack);
    push(amp;firstStack, 555);
    for(int i = 0; i < firstStack.size;   i){
        printf("#%d: %d (%p) ", i , firstStack.array[i], amp;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 freen");
    return lastValue;
}
  

Комментарии:

1. вы всегда должны использовать новую переменную указателя для сбора адреса возврата realloc , допустим, ваш третий push сбой, каким будет значение stack->array

Ответ №1:

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

неверно, потому lastAddress что может не быть адреса, выделенного через malloc() family путем добавления lastIndex .

Удалите строку

     free(lastAddress);
  

Если вы хотите, чтобы система изменила выделенный размер, вам следует изменить строку на

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

Ответ №2:

Это проблема:

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

Аргументом to free должно быть значение адреса, возвращаемое из malloc , calloc , или realloc — вы не можете освободить память по произвольному адресу, даже внутри динамически выделяемого блока.