Начнем с демонстративной программы.
Вот, пожалуйста.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
size_t n = 14;
char *s = malloc( n );
if ( s != NULL )
{
strcpy( s, "Hello World!" );
puts( s );
}
free( s );
return 0;
}
Вывод программы:
Hello World!
Итак, в этом объявлении
char *s = malloc( n );
выделено достаточно памяти для хранения строкового литерала "Hello World!"
. Однако системе может не хватить памяти. В этом случае возвращаемое функцией mallo c значение указателя будет равно NULL.
Поэтому перед использованием выделенной памяти мы проверяем, была ли память выделена успешно.
if ( s != NULL )
Если это так, то мы можем скопировать строковый литерал "Hello World!"
в выделенную память.
strcpy( s, "Hello World!" );
Обычно новички допускают ошибку. Вместо копирования строкового литерала (или какой-либо другой строки) в выделенную память они просто пишут
s = "Hello World!";
. После этого назначения адрес выделенной памяти теряется, и указатель s
теперь указывает на память. занято строковым литералом вместо выделенной памяти. В результате происходит утечка памяти.
Когда нам не нужен объект, хранящийся в выделенной памяти, память должна быть освобождена.
free( s );
Это все в первый раз.
Обычно, когда вы выделяете память для массива N
элементов, имеющих тип T
(где T
- произвольный тип), вам нужно написать
T *p = malloc( N * sizeof( T ) );
Например, если вы хотите выделить массив из 10 целых чисел, вы должны написать
int *p = malloc( 10 * sizeof( int ) );
sizeof( char )
всегда равно 1
. Таким образом, в демонстрационной программе выше я написал
char *s = malloc( n );
, потому что это то же самое, что и
char *s = malloc( n * sizeof( char ) );
Также в C нет необходимости приводить возвращенное значение mallo c как
T *p = ( T * )malloc( N * sizeof( T ) );
, потому что функция malloc
возвращает указатель типа void *
, который может быть неявно преобразован в указатель на объект любого другого типа. Вы можете использовать приведение для самодокументирования вашего кода.
В отличие от C в C ++ такого неявного преобразования нет. Так что в C ++ вы должны использовать приведение
T *p = ( T * )malloc( N * sizeof( T ) );