2009-03-04 4 views
11

Я установил буфер в размер 100. Я отображаю буфер в основной функции, где объявлен буфер. Однако, когда я передаю буфер функции и получаю sizeof '4', Я думал, что это должно быть 100, так как это размер буфера, который я создал . выход: Размер буфера: 100 SizeOf (буфер): 4Передача буфера символов в функции и получение размера буфера

#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

Что происходит, когда вы передаете массив в функцию, вы только передать адрес массива в памяти, а не размер массива. Какой sizeof (buffer) выводится в load_buffer() - это размер указателя, который равен четырем байтам.

Лучший способ сохранить размер буфера в функции изменить функцию:

void load_buffer(char *buffer, int length); 

и вызов:

load_buffer(buffer, sizeof(buffer)); 

, а затем использовать длину, когда вы хотите размер буфера.

8

С OP

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

Даже если вы можете себе представить, что load_buffer() передается buffer по refrence, что на самом деле происходит, вы передаете указатель на char по значения. Фактический массив не передается, так что нет возможности для функции load_buffer() знать размер буферной матрицы

И что же такое sizeof(buffer)? Он просто возвращает размер указателя на char. Если load_buffer() нуждается в размере buffer, он должен быть передан speratly.

Или вы можете создать новую структуру, которая содержит в себе как массив символов и размер массива, и передать указатель на эти структуры вместо того, чтобы, таким образом буфер и ее размер всегда вместе;)

20

В ответы Митча Пшеница и хафеза совершенно правильны и точны. Я собираюсь показать некоторую дополнительную информацию, которая иногда может оказаться полезной.

Обратите внимание, что то же самое происходит, если вы скажете, что компилятор у вас есть массив нужного размера

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

массив в качестве параметра только декларирует указатель. Компилятор автоматически изменяет это значение на char *name, даже если оно было объявлено как char name[N].

Если вы хотите, чтобы заставить звонящие передавать массив только размера 100, вы можете принять адрес массива (и типа того) вместо:

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

Это указатель на массив, имеют в основном, поэтому вам нужно разыменовать функцию для получения массива. Индексация затем делаются

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

Никто, я знаю, что делаю это, и я ни делал это сам, потому что это довольно усложняет прохождение аргумента. Но хорошо знать об этом. Вы можете вызвать функцию, как это тогда

load_buffer(&buffer) 

Если вы хотите принять другие размеры тоже, я бы с опцией ближнего N другие два ответа рекомендовать.

+1

+1 Для выполнения дополнительных усилий – Tom