Во-первых, вы должны понимать, что sizeof (xxx), где xxx - любое выражение левого значения (переменная), всегда эквивалентно типу sizeof () типа xxx * 1006. *). Следовательно, то, что действительно делает ваш sizeof (str), возвращает размер char *, то есть размер любого другого указателя. В 32-битной архитектуре вы получите 4, в 64-битной архитектуре это будет 8 и т. Д.
Итак, как и другие объяснили, вы должны знать длину строки, которую вы хотите выделить, а затем добавить 1 для хранения терминала \ 0, C неявно используется для помещения в конец строк.
Но чтобы делать то, что вы хотите (скопировать строку и выделить необходимое пространство), будет проще и эффективнее использовать strdup , который делает именно это: a malloc и a strcopy .
Вы также не должны забывать освободить место, которое вы выделили самостоятельно (используя malloc, calloc, strdup или любую другую функцию выделения). В C он не исчезнет, когда выделенная переменная выйдет из области видимости. Он будет использоваться до конца программы. Это то, что вы называете утечкой памяти.
#include <string.h> /* for strdup, strlen */
#include <stdio.h> /* for printf */
int main()
{
char * str = "string";
char * copy = strdup(str);
printf("bytes at least allocated for copy: %d\n", strlen(copy)+1);
printf("%s\n", copy);
free(copy);
}
И последнее замечание: я изменил сообщение на байт, по крайней мере, выделенных , потому что вы не знаете размер, выделенный при вызове malloc. Это довольно часто выделяет немного больше места, чем вы просили. Одна из причин заключается в том, что во многих диспетчерах памяти свободные блоки связаны друг с другом с использованием некоторой скрытой структуры данных, и любой выделенный блок должен содержать хотя бы такую структуру, другая заключается в том, что выделенные блоки всегда выровнены таким образом, чтобы быть совместимыми с любым типом выравнивание.
Надеюсь, это поможет вам немного лучше понять C.