передача буфера char в функции и получение размера буфера

Я установил буфер на размер 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: %dn", sizeof(buffer));
    load_buffer(buffer);

    return 0;
}

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

4 ответов


вы используете размер указателя на буфер (4 байта), а не размер буфера.

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

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

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

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

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));
}

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

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

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

load_buffer(&buffer)

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


из ОП

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

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

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

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


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

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

void load_buffer(char *buffer, int length);

и звонок:

load_buffer(buffer, sizeof(buffer));

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