2012-10-10 4 views
3

가능한 중복 : 내 실수이고
Realloc is not resizing array of pointersrealloc을 변경하지 않는 크기

사람이 말해 줄래? 이 함수는 stdin에서 제공된 문자 배열을 만들어야합니다. 나는 몇 가지 관련 질문을 읽었지 만, 이해하기에는 너무 복잡했습니다.

char *readChar(void) 
{ 
    int c; 
    int len = 0; 
    char* parr = malloc(sizeof(char)); 

    while((c = getchar()) != EOF) 
    { 
     ++len; 
     int size = sizeof(char)*len; 
     parr = (char *) realloc(parr,size); 
     *(parr+size-1) = (char) c; 
     printf("Done! Size should be: %dB, but real size is %dB\n",size,sizeof(parr)); 
    } 

    return parr; 
} 

출력 :

가 완료! 크기는 다음과 같아야합니다. 1B, 실제 크기는 8B 완료! 크기 : 2B, 실제 크기는 8B이어야합니다. 완료! 크기는 다음과 같아야합니다. 3B, 실제 크기는 8B 완료! 크기는 다음과 같아야합니다. 4B, 실제 크기는 8B입니다.

답변

7

실수로 할당 한 바이트 수는 알려지지 않습니다. char *

원하는 사운드는 올바른 크기의 메모리를 할당했는지 확인하는 것과 같습니다. sizeof()는 그러한 정보를 제공하지 않습니다. 이 시점에서 세부 사항은 매우 낮습니다. OS에 의존하는 작업을 수행하여 해당 정보를 찾으십시오. (예. 리눅스 커널에 당신이 kmalloc() 메모리 당신이있어 정확히 얼마나 많은 바이트를 찾아 ksize()를 사용할 수있는 경우)

2

sizeof(parr)이 할당 된 공간의 양하지, 그것은 char*의 크기 (parr의 데이터 타입)입니다 . 할당 한 메모리 양을 알 수있는 유일한 이식 가능한 방법은 직접 추적하는 것입니다.

예상 한대로 realloc이 작동한다고 가정하면 할당 한 바이트 수는 변수 size과 같습니다.

내가 코드에서 발견 그냥 다른 몇 가지 : 그것은 성공하도록

char* parr = malloc(sizeof(char)); 

당신은 항상 malloc의 반환 값을 확인해야합니다을 :

char* parr; 
if(!(par = malloc(sizeof(char))) 
{ 
    //allocation failed 
} 

코드의 다음 부분 내 눈을 사로 잡은 사람 :

int size = sizeof(char)*len; 

실제로는 필요하지 않습니다. sizeof(char)은 항상 1 바이트와 같으므로 루프의 각 반복에서 len * 1과 같은 새 변수를 선언하는 대신 현재 값 len을 사용할 수도 있습니다.

언급 한 바와 같이
parr = (char *) realloc(parr,size); 

이전이 len에 equivelent 때문에 당신이 size를 사용할 필요가 없습니다.실패 넣다 또한 C에서이 포인터를 캐스팅하는 것은 좋은 생각이 일반적으로하지 않습니다, 당신은 또한 realloc과의 리턴 값을 검사해야합니다 :

if(!(parr = realloc(parr, size))) 
{ 
    //allocation failed 
} 

realloc 기능을 사용할 때 항상 버퍼를 사용하는 마지막 참고로 잠재적 인 메모리 문제를 피하십시오.

char *readChar(void) 
{ 
    int c, len = 0; 
    char* parr = NULL, char *tmp; 

    if(!(parr = malloc(sizeof(char))) 
    { 
     fputs("memory allocation failed", stderr); 
     exit(1); 
    } 

    while((c = getchar()) != EOF) 
    { 
     ++len; 
     if(!(tmp = realloc(parr, len))) 
     { 
      free(parr); 
      fputs("memory allocation failed", stderr); 
      exit(1); 
     } 
     parr = tmp; 
     *(parr+len-1) = (char) c; 
    } 
    return parr; 
} 
1

sizeof(parr)가 (시스템에 8 바이트) 포인터의 크기를 반환 : 여기에 코드를 내 스핀입니다. 실제 문자열 크기를 확인하려면 strlen을 사용해야합니다. 단, 문자열은 \0으로 끝나야합니다 (즉, null로 끝나야 함).

1

컴파일 중에 평가되므로 sizeof()로 동적으로 할당 된 배열의 크기를 측정 할 수 없습니다. 그리고 귀하의 예제에서 포인터의 크기를 취하고 x64 아키텍처에서 8B입니다.

1

인쇄 할 때마다 항상 동일한 포인터 인 sizeof을 제공합니다.

포인터로 가리키는 메모리의 크기를 알 수있는 방법이 없으므로 직접 추적해야합니다.

제쳐두고, sizeof(char)은 항상 1입니다. 그러므로 reallocmalloc으로 전화를 걸어서 제거 할 수 있습니다. 또한 malloc과 realloc의 반환 값을 확인하여 안전성을 확인해야합니다.

관련 문제