2012-02-04 3 views
20

realloc의 작동 방식을 이해하는 데 어려움을 겪고 있습니다. 내가 버퍼를 malloc으로 할당하고 그 버퍼에 데이터를 복사 한 경우의는 "AB"를 가정 해 봅시다 : reallocing 후 버퍼의 데이터가 손실됩니까?

+------------+ 
| A | B | \0 | 
+------------+ 

다음 내가 버퍼를 realloc'ed, 데이터 (심지어 단일 바이트)에서 길을 잃었 어떤이 될 것인가? ; 아니면 단지 버퍼를 확장합니까? :

+------------------------+ 
| A | B | \0 | ? | ? | ? | 
+------------------------+ 

번호 :

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

int main(void){ 

    char* buffer = (char*) malloc(sizeof(char) * 3); 
    strncpy(buffer, "AB", 2); 

    buffer   = (char*) realloc(buffer, sizeof(char) * 6); /* Will there be any lost here? */ 
    free(buffer); 
    return(0); 
} 

답변

39

원래 메모리 블록의 내용을 보유 할 블록의 크기를 증가시키는 realloc. 메모리 블록을 배치 할 때 크기를 조정할 수 없더라도 이전 데이터는 새 블록에 복사됩니다. 블록 크기를 줄이는 realloc의 경우 이전 데이터는 잘립니다.

realloc으로 전화하면 어떤 이유로 realloc이 실패하는 경우 데이터가 손실된다는 의미입니다. 이것은 reallocNULL을 반환하여 실패하지만 그 경우 원래 메모리 블록은 여전히 ​​유효하지만 포인터를 덮어 썼기 때문에 더 이상 액세스 할 수 없으므로 NULL입니다. 또한이 malloc 반환 값 캐스팅 것을

newbuffer = realloc(buffer, newsize); 
if (newbuffer == NULL) 
{ 
    //handle error 
    return ... 
} 
buffer = newbuffer; 

참고 C에서 불필요하고 sizeof(char)1 같 정의된다 :

표준 패턴이다.

+0

가 왜'= realloc을 (버퍼, newSize와)을 버퍼링 할 수없는 잘못,'? –

+1

이유는 대답 –

+0

에 설명되어 있습니다. 그렇기 때문에 데이터 손실을 방지하려면 먼저 할당이 성공적인지 확인한 다음 다시 할당하십시오. 감사합니다. –

4

아무것도 없어지지 않습니다. 하지만 실제로는 realloc() (및 이전의 malloc())이 "작동"했는지 테스트해야합니다.
또한 malloc의 반환 값에 대한 캐스트는 기껏해야 중복되어 컴파일러가 없을 때 catch 한 오류를 숨길 수 있습니다. 당신이 문자열을 원하는 가정에 기초

strncpy의 사용량은

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

int main(void) { 
    char *buffer = malloc(3); 
    if (buffer == NULL) /* no memory */ exit(EXIT_FAILURE); 

    strncpy(buffer, "AB", 2); 
    /* ATTENTTION! ATTENTION: your array is not a string. 
    ** buffer[2] is not the zero string terminator */ 

    // buffer = realloc(buffer, 6); /* Will there be any lost here? */ 
    /* If realloc returns NULL, you've just lost the only pointer to 
    ** the allocalted memory, by overwriting it with NULL. 
    ** Always `realloc` to a temporary variable */ 
    char *tmp_buffer = realloc(buffer, 6); 
    if (tmp_buffer == NULL) { 
     /* realloc failed */ 
    } else { 
     /* realloc worked, no bytes lost */ 
     buffer = tmp_buffer; 
     /* ATTENTION! ATTENTION: buffer is still not a string 
     ** buffer[0] is 'A', buffer[1] is 'B', 
     ** all other elements of buffer are indeterminate */ 
    } 

    free(buffer); 
    return(0); 
}