передача char-буфера в функции и получение размера буфера - PullRequest
11 голосов
/ 04 марта 2009

Я установил размер буфера 100. Я отображаю буфер в основной функции, где он объявлен. Однако, когда я передаю буфер функции и получаю размер '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));
}

Ответы [ 4 ]

21 голосов
/ 04 марта 2009

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

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

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)

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

21 голосов
/ 04 марта 2009

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

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

void load_buffer(char * buffer, size_t bufSize)
{    
    ...
}
8 голосов
/ 04 марта 2009

С ОП

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

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

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

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

4 голосов
/ 04 марта 2009

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

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

void load_buffer(char *buffer, int length);

и вызов:

load_buffer(buffer, sizeof(buffer));

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

...