Как вызвать calloc() ровно 25 байт

Я хочу точно вызвать 25 байтов памяти. В данном случае msg_len = 5 байт, так как это входные данные. Это код, который у меня есть:

  int full_msg_size = 20 + msg_len;
  printf("full_msg_size: %d\n", full_msg_size);
  void *full_msg = calloc(full_msg_size, sizeof(char));
  printf("size of full_msg: %d\n", (int*)sizeof(full_msg));

Вот что распечатывает:

full_msg_size: 25 размер full_msg: 8

Но я хочу, чтобы размер full_msg равнялся 25 байтам, как и full_msg_size.

Я также хочу, чтобы все области памяти были инициализированы нулем.

Может ли кто-нибудь сказать мне, как правильно calloc/malloc?

Спасибо


person umdcoder    schedule 24.10.2014    source источник
comment
sizeof(char) всегда равно 1, поэтому вы можете просто написать 1.   -  person glglgl    schedule 17.01.2015


Ответы (4)


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

`int len = strlen(some_str)`    

Возможно, вы получаете full_msg_size: 25 размера full_msg: 8, потому что sizeof
возвращает размер адреса full_msg.

Итак, ваша функция:

printf("size of full_msg: %d\n", (int*)sizeof(full_msg));  

Должно быть:

printf("length of full_msg: %d\n", strlen(full_msg));

если вы хотите выбрать ровно 25 байт памяти:

char *full_msg = {0};
full_msg = calloc(25, 1); //all space initialized to 0     
//or you can also use:  
full_msg = malloc(25);  

full_msg теперь имеет память ровно на 25 байт (однако нужно использовать для '\0')

Оператор sizeof при использовании с char *str возвращает вам размер char *, который является просто адресом.

Примечание. Размер адреса (или указателя) не всегда будет 8 байт только потому, что вы работаете на 64-битной машине, это зависит от того, во что скомпилировано приложение: 32-битное или 64-битное. т. е. для 32-битного приложения размер адреса составляет 4 байта, для 64-битного приложения он будет равен 8 байтам.

person ryyker    schedule 24.10.2014

Скорее всего, вы выделяете правильное количество байтов, но спрашиваете, насколько велик указатель на пустоту. А на 64-битной машине это, скорее всего, будет 8 байт. Если ему не удалось выделить запрошенный вами объем памяти, тогда full_message будет иметь значение NULL.

person Matthew V Carey    schedule 24.10.2014

Оператор sizeof (почти всегда) является оператором времени компиляции (исключение: VLA). Таким образом, указатель sizeof some всегда один и тот же (на вашей машине он всегда равен 8) и не зависит от размера, переданного какой-либо функции malloc или calloc.

Учитывая указатель malloced или calloced, нет переносимого способа узнать размер, запрошенный во время его выделения. Вы должны сохранить этот размер где-нибудь! Вы можете использовать элемент гибкого массива, например здесь, если хотите сохранить этот динамический размер внутри выделенная структура. Вы часто сохраняете размер в другом месте, то есть в какой-то переменной (full_msg_size в вашем случае).

Итак, ваш calloc работает (кстати, вы должны проверить его на предмет отказа).

void *full_msg = calloc(full_msg_size, 1);
if (!full_msg) {perror("calloc"); exit(EXIT_FAILURE); };

Но вы не можете использовать sizeof для вычисления размера среды выполнения выделенной зоны.

person Basile Starynkevitch    schedule 24.10.2014
comment
sizeof - это всего лишь своего рода вещь во время компиляции в C. C - это странно. - person Kerrek SB; 24.10.2014

Вы печатаете размер указателя, который будет равен 8 байтам в случае 64-битных машин.

person Karthik Balaguru    schedule 24.10.2014
comment
размер указателя, который будет равен 8 байтам в случае 64-битных машин. Не всегда верно. Только если цель для приложения, использующего код, скомпилирована как 64-битная. Многие приложения, даже созданные на 64-битной машине, построены как 32-битные. В этом случае размер адреса (указателя) будет 32 бита или 4 байта. - person ryyker; 24.10.2014
comment
Да, я тоже имел в виду только тот же момент, но не упомянул его явно. - person Karthik Balaguru; 24.10.2014