2017-12-07 22 views
2

아래에 문제를 나타내는 간단한 C 프로그램이 있습니다. 포인터를 사용하여 realloc에 전화를 걸면 올바르게 작동하지만 포인터에 오프셋을 추가하려고하면 (예 : 배열의 이후 요소에서 시작) 실패합니다.포인터에 오프셋이있을 때 realloc이 충돌합니다.

10361264,0,0,2 

그리고 충돌 : realloc(num->bytes+1,num->len-1);-realloc(num->bytes,num->len); 이것에 출력/동작을 변경하는 변경 위의 코드에서,

9247152,0,0,2 
Realloc successful. 

을 :하지만 일례로서

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

struct arbNum{ 
    unsigned char* bytes; 
    long len; 
}; 

void trim(struct arbNum* num){ 
    printf("%d,%d,%d,%d\n",num->bytes,num->bytes[0],num->bytes[1],num->len); 
    unsigned char* nbytes = realloc(num->bytes,num->len); 
    printf("Realloc successful.\n"); 
    num->bytes = nbytes; 
} 

int main(void){ 
    struct arbNum p = {calloc(2,1),2}; 
    trim(&p); 
} 

,이 출력 . 그것은 포인터를 전혀 이해하지 못하는 것일 수도 있지만, 현재 이해할 수있는 점은 본질적으로 다른 값이 저장되는 주소라는 것입니다. 이 경우 pointer+1을 제공하는 것이 왜 포인터보다 하나 높은 주소에 저장된 값을 가리 키지 않겠는가? 즉, 그 포인터가 가리키는 배열의 첫 번째 요소로 작용할 것입니다. 내가 뭘 하려는지 num.bytes에 의해 가리키는 배열을 복사하는 첫 번째 요소에서 새 주소로 메모리,하지만 분명히, 그것은 어떤 이유로 실패하고있다.

답변

7

아니요, malloc() 또는 패밀리가 이전에 반환 한 실제 포인터에 대해서만 realloc() 만 가능합니다.

그렇지 않으면 C11을 인용 undefined behavior

, 장 §7.22.3.5

ptr가 널 포인터 인 경우는 realloc 기능은 지정된 크기의 malloc 기능처럼 동작,입니다. 그렇지 않고 ptr이 메모리 관리 함수에 의해 반환 된 포인터와 일치하지 않거나 free 또는 realloc 함수 호출로 공간 할당이 해제 된 경우 동작은 정의되지 않습니다. [...]

그래서, 당신은 아니에요 realloc()에 그 전달, 새로운 주소를 생성 이동 aritmatic 포인터를 사용하고 아무 의미가 부분적으로 재 할당 할 기대을 허용했다.

+0

오른쪽. 그리고 분명히 내가 원하는 것을하기 위해'memcpy'를 사용할 수 있습니다. – user2649681

+0

@ user2649681 음, 그 전에도 UB를 칠 것입니다. –

+0

@ user2649681 "분명히 나는 ​​memcpy를 사용하여 내가 원하는 것을 할 수있다"-> 의심 스럽다. 그러나'memmove()'가 작동 할 수도 있습니다. – chux