2014-03-06 1 views
0

아래 코드를 실행하면 주어진 결과가 나타납니다.C realloc 문자 배열의 겉보기 크기가 변경되지 않습니다.

#include <stdio.h> /* printf */ 
#include <stdlib.h> /* malloc, realloc */ 

int main() 
{ 
    char* characters = (char *) malloc(10 * sizeof(char)); 
    printf("Before: characters at %p, size=%lu\n", (void *) characters, sizeof(characters)/sizeof(characters[0])); 
    char* temp = (char *) realloc(characters, 100); 
    if (temp) 
    { 
     printf("After realloc, characters size = %lu, temp size = %lu\n", sizeof(characters)/sizeof(characters[0]), sizeof(temp)/sizeof(temp[0])); 
     printf("After realloc, nums at %p, temp at %p\n", (void *) characters, (void *) temp); 
     //characters = temp; 
     free(temp); 
    } 
    free(characters); 
} 

/* Output: 
Before: characters at 0x107b00900, size=8 
After realloc, characters size = 8, temp size = 8 
After realloc, nums at 0x107b00900, temp at 0x107b00910 
test(3556) malloc: *** error for object 0x107b00900: pointer being freed was not allocated 
*** set a breakpoint in malloc_error_break to debug 
Abort trap: 6 
*/ 

나는 무엇이 고장 났는지 알아 내려고하고있다. malloc은 10 개의 연속 문자를위한 공간을 제쳐두고 그 배열의 첫 번째 요소에 대한 포인터를 제공한다고 생각합니다. 포인터를 characters에 저장합니다. 그런 다음 characters 크기를 인쇄하고 10을 기대하지만 8이됩니다. 처음으로 이상한 점입니다. 그런 다음 realloc에게 100 개의 연속 된 문자를위한 공간이 있고 첫 번째 지점에 대한 포인터를 나에게 반환하는 힙에서 새로운 위치를 찾도록 요청합니다. 포인터를 임시 변수에 넣습니다. temp의 크기를 인쇄 할 때 100이 되더라도 다시 8이됩니다. characterstemp에 대한 포인터를 인쇄하면 힙에 두 개의 다른 위치가 표시됩니다. 대개는 temp이 가리키는 포인터를 가리 키도록 characters 포인터를 다시 할당합니다. 그렇다면 내 포인터를 무료로하려고했는데 0x107b00900을 풀어 낼 수 없다고 말하면 정확한 위치는 characters입니다. 그 시점의 객체는 malloc에 없습니다. 그러나, 나는 malloccharacters을위한 공간을했다. 왜 이런 일이 일어나는 걸까요? malloc, realloc, sizeof 등의 기능을 잘못 이해하고 있습니까? 도와 줘서 고마워.

+0

그런 포인터에 sizeof를 사용할 수 없습니다. 그리고 mem 2x를 해제하십시오. –

+0

포인터가 가리키는 배열의 크기를 가져 오는 데 사용할 수있는 함수는 무엇입니까? '임시'와 '캐릭터'는 다른 장소에 있습니다. 맞습니까? 그래서 나는 어디에서 두 번 풀어주는거야? – sredmond

+2

@sredmond. 없음, 할당 된 크기를 직접 추적해야합니다. 성공하면'realloc()'문자로'else free (문자)'를해야합니다. – chux

답변

3

할당 된 메모리 양을 얻기 위해 포인터에 sizeof를 사용할 수 없습니다.

char* characters = (char *) malloc(10 * sizeof(char)); 

변수 characters 변수는 얼마나 많은 공간을 가리키는 지 알 수 없습니다. 그것을 추적하는 것이 당신 직업입니다. 여기에 무슨이다 -

지금까지

char* temp = (char *) realloc(characters, 100); 

으로 realloc을 메모리 블록을 이동할 수 있습니다. 그럴 때 원래 문자가 가리키는 메모리를 할당되지 않은 것으로 표시합니다. 따라서 마지막 행에서 문자를 사용할 수 없게되면 시스템에서 할당되지 않은 것으로 표시된 메모리를 해제하기 때문에 오류가 발생합니다.

+3

물론 가능합니다. 포인터의 크기를 알려줍니다. –

+0

확인. 당신 말이 맞아요. –

+0

가능 합니다만, 포인터의 크기 (32 비트 시스템에서는 4)가 OP에서 필요로하는 것이 아닙니다. –

3

alloc/realloc에 의해 할당 된 실제 크기를 찾는 방법은 없습니다. 크기가 *characterscharacters의 크기로 나누는 트릭은 배열에서만 작동합니다. 포인터는 이 아니고이됩니다.

라이브러리는 표준 라이브러리의 사용자가 사용할 수있는 방식으로 할당 된 메모리 청크의 크기를 추적하지 않습니다. 자체적으로 사용하기 위해 일부 정보를 저장할 수 있지만이를 검색하는 사용자 대면 호출이 없습니다.

이 문제를 해결하는 일반적인 방법은 할당 된 영역에 대한 포인터와 함께 할당 크기를 저장하는 것입니다.

+0

감사합니다! 이것이 내가 알 필요가있는 것입니다. – sredmond

+0

나는 보통 할당의 크기가 아닌 realloc을 사용할 때마다 (항목 수)와 (항목에 대한 포인터)를 저장합니다. 나에게 더 읽기 쉽게 보인다. 그리고 언제든지 재 할당하기를 원하지 않는다면, 지금 당장 필요한 것보다 조금 더 할당하는 경우가 많으므로, 항목이 하나 더 필요할 경우 다시 할당 할 필요가 없습니다. 이 경우 트리플이 있습니다 (할당 된 항목 수, 사용중인 항목 수, 할당 된 항목에 대한 포인터). – gnasher729

관련 문제