2014-01-26 2 views
1

나는 다음과 같은 코드를 가지고 erroring하지, 아무것도 diong하지 :realloc을 단순히

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

int main(int argc, char ** argv) 
{ 
    //just checking to see where the stack 
    printf("The stack is around %p\n", &argc); is, making sure arr isn't in it 
    char ** arr = malloc(8*sizeof(char*)); 
    printf("arr is size %li, at %p\n", sizeof(arr), arr); 
    arr = realloc(arr, 100); //I picked a weird number to show it isn't doing anything. I've picked different numbers (like 200, 2*sizeof(char*)*sizeof(arr), and 16) 
    printf("arr is size %li, at %p\n", sizeof(arr), arr); 
} 

파일의 전체이다 (이것은 단위 테스트입니다, 나는 다른 곳을 알아 차리지했다)

출력을

The stack is around 0x7fff5b94d12c 
arr is size 8, at 0x120f010 
arr is size 8, at 0x120f010 

아마도 내가 realloc이해야 할 일을 오해하고 있습니다. 나는 을 기대하고 다음 출력을 기대합니다. <size>

The stack is around 0x7fff5b94d12c 
arr is size 8, at 0x120f010 
arr is size <size>, at <somewhere> 

... (12)와 같은 뭔가 이상한 ... 적어도 8 <somewhere>은 대부분 0x120f010 그러나 가능 어디서나 합리적이다.

내 기대가 잘못되었거나 realloc을 잘못 사용하고 있습니까? 포인터의 크기를 변경하려고하고가 참조하는 메모리의 양을 말하려고하지 않는 포인터의 크기를 참가하는

sizeof char** 

와 동일합니다

+3

진짜 문제는 당신이'sizeof'를 오해하고 있다는 것입니다 ... –

+0

당신 말이 맞아요. 고맙습니다 ... 이제 원본 프로그램을 디버그하십시오. –

답변

1

프로그램의 출력이 올바른지,

  • 어느 mallocrealloc가 자동 스토리지 (즉, "스택")와 아무 상관이 있기 때문이다. 동적 저장 영역 (즉, "힙")에서 메모리를 할당합니다. malloc, realloc 또는 그 밖의 다른 기능에 대한 호출에 응답하여 스택 상단의 위치가 변경 될 것으로 예상해서는 안됩니다.
  • sizeof(arr) 값은 사용자가 할당 한 값에 따라 다릅니다. 컴파일 타임에 계산되며 항상 포인터의 크기와 같습니다. 시스템에서 포인터는 8 바이트를 사용합니다.
  • malloc은 종종 더 많은 메모리를 제공하며 실제 값을 realloc이 나중에 액세스 할 수있는 특수한 위치에 저장합니다. realloc 다운 또는 범위 내 realloc 인 경우 realloc에 의해 반환 된 값은 변경되지 않습니다. 그것이 단순히 mallocmemcpy을 호출하는 것보다 더 나은 성능을 낼 수있는 이유입니다.
+0

답장을 보내 주셔서 감사합니다 (Ed의 것이 가장 좋았지 만, 제가 가장 정확하게 찾아 냈습니다). 스택 대 힙에 관해서는, 나는 단지 mallocing이 잘못되어 있지 않은지 확인하고 스택의 일부분을 쓰려고했다. 원래 프로그램에서 특정 문자열이 덮어 쓰여지고있는 것처럼 보이는 문제를 얻었습니다 (필요한 공간보다 훨씬 작은 공간을 재 할당했기 때문에). –

1
sizeof arr 

. 포인터는 배열이 아니며 컴파일시에 sizeof이 계산됩니다.

주소 비트의 경우 realloc은 메모리 블록이 이동 된 것을 보장하지 않습니다. 단순히 성공적으로 확장하고 동일한 주소를 반환 할 수 있습니다.

또한 예제 코드 일 뿐이지 만 realloc에 오류가 발생하면 arr이 처음으로 유출되었음을 알게됩니다.

+2

Pedantic : C99에서'sizeof'는 런타임 연산이 될 수 있습니다 (가변 길이 배열에서 사용되는 경우). http://stackoverflow.com/q/10078283/575615 – Medo42

+0

@ Medo42 : 아, 네, 잘 부탁드립니다. 나는 지금 C89 땅에 C를 쓰고 있었는데, 그것에 대해 생각하지 않았다. –

0

그것은 드문 일이 아니에요, 그리고 malloc 호출이 포인터의 주소를 변경하지 않을 realloc 바로 사용한다는 사실에 약간은 기대했다. 대부분의 경우 할당자는 주소에서 예약 된 메모리 양을 확장 할 수 있으며 포인터를 이동할 필요가 없습니다. 이것이 여기서 일어나는 일입니다.

이것은 당신이 의존해야하는 것이 아닙니다. 그것은 구현의 단점입니다

+0

이 질문에 초점을 맞추고있는 것은 전혀 아닙니다. –

0

realloc()이 다른 포인터를 반환해야한다고 가정하면 잘못된 가정입니다. 일반적으로 당신이 크기를 증가하는 경우는 할당 된 메모리의 크기를 줄이거 나 "있는 그대로"다음 realloc() 등, 때로는

를 같은 포인터를 반환하고 데이터 복사를 방지 할 수 있습니다 그것을 떠나하는 경우

할당 된 메모리 realloc()의 경우 기존 공간 위에 여유 공간이 있는지 확인하고 여전히 동일한 포인터를 반환하고 데이터 복사를 피할 수 있습니다.

대부분 할당 된 메모리 위에 여유 공간이없는 경우에만 realloc()은 다른 곳으로 데이터를 복사하고 다른 포인터를 반환해야합니다.