2012-11-13 4 views
1

끝내는 void *가있는 유연한 배열을 가진 C로 간단한 스택 프로그램을 작성하고 있습니다. 배열로 밀어 넣는 데 더 많은 요소가 필요할 때 realloc()을 사용하여 새 스택을 만들고 이전 스택을 해제 한 다음 새 스택을 이전 스택에 할당합니다. (현재 pop ​​() 함수가 없습니다.). 하지만 괜찮 printstack 개까지glibc가 감지되었습니다 - double free 또는 corruption

*** glibc detected *** ./prog: double free or corruption (fasttop): 0x096ee008 *** 
======= Backtrace: ========= 
/lib/libc.so.6[0xb7721fd4] 
/lib/libc.so.6(cfree+0x9c)[0xb772387c] 
./prog[0x8048731] 
./prog[0x8048461] 
======= Memory map: ======== 

출력() : 나는 모든 메시지가 표준 오류로 인쇄됩니다 수행하고 주() 이후에() 스택 해제 할 때

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

typedef struct Stack 
{ 
    int top, length; 
    void* start_ptr[]; 
} Stack; 

Stack* init_stack(int n_items) 
{ 
    Stack* stack; 
    stack = malloc(sizeof(int) * 3 + sizeof(void*) * n_items); 

    stack->top = -1; 
    stack->length = n_items; 

    return stack; 
} 

Stack* increase_stacksize(Stack* stack, int n_itemsToAdd) 
{ 
    Stack* newstack;  
    newstack = realloc(stack, sizeof(*stack) + sizeof(void*) * (n_itemsToAdd + stack->length)); 

    if(newstack != NULL) 
     //printf("\nDebug print - array reallocated\n"); 

    free(stack); 
    stack = newstack; 

    stack->length += n_itemsToAdd; 

    return stack; 
} 

Stack* push(Stack* stack, void* item) 
{ 
    if(stack->top + 1 == stack->length){ 

     stack = increase_stacksize(stack, 10); 
    } 

    int pos = stack->top + 1; 

    stack->start_ptr[pos] = item; 
    ++(stack->top); 

    return stack; 
} 

void printstack(Stack* stack) 
{ 
    printf("Number of items in the stack = %d\n", stack->top + 1); 
    printf("Capacity of the stack = %d\n", stack->length); 

    printf("Elements in the stack are: \n"); 

    int i; 

    for(i = 0; i <= stack->top; i++){ 
     int* item_ptr; 
     void* address; 

     address = stack->start_ptr[i]; 

     item_ptr = (int*)address; 

     printf("Position = %d, Item = %d \n", i, *item_ptr); 
    } 
} 

int main(void) 
{  
    Stack* stack; 
    stack = init_stack(5); 

    int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
    int i; 

    for(i = 0; i < 10; i++) 
    { 
     stack = push(stack, (void*)(a+i)); 
    } 

    printstack(stack); 

    free(stack); 

    return 1; 
} 

문제입니다. 무료 (스택) 행을 제거하더라도 런타임 오류가 ideone.com에 발생하지만 표준 오류 메시지는 없습니다. 나는 크기가 0 인 배열 때문에 뭔가 있을지도 모른다고 추측하고있다. 여기서 문제가 될 수있는 것은 무엇입니까? 필요한 경우 당신 reallocincrease_stacksize

+1

ideone의 런타임 오류는 'main'에서 1을 반환하기 때문에 발생할 수 있습니다. – interjay

답변

6

realloc는 기존의 블록을 해제합니다. 그냥 free이 제거 :

free(stack); // remove this line 
stack = newstack; 

을 성공적으로 realloc 후, 함수에 의해 반환 된 주소는 원본과 동일하게 보장 할 수 없습니다. 동일하면 메모리가 두 번 해제됩니다. 동일하지 않으면 할당되지 않은 메모리 위치가 해제됩니다.

간략히 말하면 freerealloc 이후의 원본을 사용하지 마십시오.

+2

또한 'if newstack == NULL'행을 삭제해야합니다. 그 이후의 행은 주석으로 처리됩니다! – Roddy

+0

오 줄을 주석을 잊어 버렸습니다. 대답 해줘서 고마워. 나는 그것을 몰랐다. 메모리가 malloc, calloc 또는 realloc로 할당 된 경우 K & R은 use free를 씁니다. realloc이 크기를 "변경"한다고 말한 것처럼 realloc이하는 일을 완전히 이해하지 못했습니다. 다시 한번 감사드립니다. – Andariel

2

free(stack) 줄을 제거하고 원래의 stack을 해제해야하므로

+0

정말로 realloc이하는 일을 설명해 주셔서 감사합니다. – Andariel

관련 문제