2009-03-04 6 views
11

버퍼 크기를 100으로 설정했습니다. 버퍼가 선언 된 main 함수에 버퍼를 표시합니다. 그러나 함수에 버퍼를 전달하고 sizeof '4'를 얻었을 때 나는 그것이메인에 생성 된 버퍼의 크기이므로 100이어야한다고 생각했습니다. 출력 : 버퍼 크기 : 100 를 sizeof (버퍼) (4)함수에 char 버퍼를 전달하고 버퍼 크기를 가져옵니다.

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

void load_buffer(char *buffer); 

int main() 
{ 
    char buffer[100]; 
    printf("buffer size: %d\n", sizeof(buffer)); 
    load_buffer(buffer); 

    return 0; 
} 

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 
+2

main()에서 명시 적으로 배열을 선언하고 load_buffer()에서 포인터를 선언했습니다. 차이점은 main()에서 버퍼가 배열임을 알지만, load_buffer()에서는 컴파일러가 버퍼가 배열인지 또는 힙에 메모리가 할당되었는지 또는 구조체인지 여부를 알지 못합니다 . 컴파일러는 메모리 주소 (포인터) 만 알고 있으므로 sizeof()는 메모리 주소의 크기를 4 바이트로 반환합니다 (32 비트 컴퓨터이기 때문에 64 비트 컴퓨터 인 경우 8 비트입니다. 바이트 길이). 희망이 좀 더 이해하는 데 도움이됩니다. – AndaluZ

+0

sizeof() 함수 대신 strlen()을 사용하면 포인터 값의 크기를 반환합니다. – NandhaKumar

답변

19

이 오히려 버퍼의 크기보다, 버퍼 (4 바이트)로 포인터의 크기를 사용한다.

C에서는 버퍼 오버런이 너무 쉽고 자주 발생하는 이유 중 하나 인 버퍼의 크기를 별도로 전달해야합니다. 어떻게됩니까

void load_buffer(char * buffer, size_t bufSize) 
{  
    ... 
} 
4

, 당신은 함수에 배열을 통과 할 때, 당신은 단지, 메모리에 배열이 아닌 크기를 배열의 주소를 전달할 수 있습니다. load_buffer()에서 출력하는 sizeof (버퍼)는 포인터의 크기이며 4 바이트입니다. 에

void load_buffer(char *buffer, int length); 

하고 통화 :

load_buffer(buffer, sizeof(buffer)); 

다음 원하는 때마다 길이를 사용

기능의 버퍼의 크기를 유지하는 가장 좋은 방법은의 기능을 변경하는 것입니다 버퍼의 사이즈 영업에서

8

load_buffer()가에 refrence로 buffer를 전달 상상할 수 있지만

void load_buffer(char *buffer) 
{ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

, 정말로 일어나고있는 것은 당신이 값으로 char에 대한 포인터를 전달하는 것입니다. 실제 배열이 전달되지 않으므로 load_buffer() 함수가 버퍼 배열의 크기를 알 수있는 방법이 없습니다.

따라서 sizeof(buffer)은 무엇을하고 있습니까? 그것은 단순히 char에 대한 포인터의 크기를 리턴합니다. load_buffer()buffer의 크기를 필요로하는 경우, 그것은 speratly 전달되어야합니다.)

20

을,

또는 그 대신 구조체에 당신이 포인터를 char 배열과 배열의 크기가 모두 포함 된 새로운 구조체를 생성하고 전달할 수있는, 그런 식으로 버퍼와 그것의 크기는 항상 함께 Mitch Wheat과 hhafez의 대답은 완전히 옳았습니다. 때로는 유용 할 수있는 몇 가지 추가 정보를 보여 드리겠습니다. 당신은 당신이 적당한 크기

void load_buffer(char buffer[100]) { 
    /* prints 4 too! */ 
    printf("sizeof(buffer): %d\n", sizeof(buffer)); 
} 

매개 변수로 배열은 단지 포인터를 선언되는 배열을 가질 수 컴파일러를 말한다면 같은 일이 발생

참고. char name[N]으로 선언 된 경우에도 컴파일러에서 자동으로 해당 값을 char *name으로 변경합니다.

만 크기 (100)의 배열을 전달하기 위해 발신자를 강제하려면, 대신 배열의 주소 (그 유형을) 받아 들일 수는 :

void load_buffer(char (*buffer)[100]) { 
    /* prints 100 */ 
    printf("sizeof(buffer): %d\n", sizeof(*buffer)); 
} 

이 배열 당신에 대한 포인터입니다 main에 있기 때문에 함수를 역 참조하여 배열을 가져와야합니다. 오히려 인수의 전달을 복잡하기 때문에 인덱싱 후, 나는 그 일을 알고 난이도 그것을 자신하고 있어요

buffer[0][N] or (*buffer)[N] 

아무도하여 수행됩니다. 그러나 그것에 대해 알고있는 것이 좋습니다. 당신이 너무 다른 크기를 허용 할 경우 당신은 내가 다른 두 답변을 추천 통과-N 옵션과 함께 갈 것입니다,이 다음

load_buffer(&buffer) 

같은 함수를 호출 할 수 있습니다.

+1

+1 약간의 노력이 필요합니다. – Tom

관련 문제