Что делает malloc в этом коде? - PullRequest
5 голосов
/ 31 июля 2009

Не могли бы вы объяснить следующий код?

str = (char *) malloc (sizeof(char) * (num+1));
  1. Что здесь делает malloc?
  2. Почему используется num + 1?

Ответы [ 11 ]

29 голосов
/ 31 июля 2009

malloc - это функция , которая выделяет кусок памяти в куче и возвращает ей указатель . Это похоже на оператор new во многих языках. В этом случае он создает блок памяти, который может существовать в течение произвольного промежутка времени и иметь произвольный размер. Само по себе это довольно глубокий материал, который довольно сложно объяснить и который требует отдельного вопроса.

num + 1 компенсирует нулевой терминатор в конце строки. Строки часто должны знать, как долго они находятся, и традиция C состоит в том, чтобы выделять место для дополнительного символа в конце строки, который всегда будет специальным символом \0. Это позволяет функциям, которые работают со строкой, автоматически определять размер строки. Например, если вы хотите что-то сделать с каждым символом строки, не зная, какова длина строки, вы можете сделать что-то вроде этого:

const char *ptr = str;
while (*ptr != '\0') {
    process(*ptr);
    ptr++;
}
13 голосов
/ 31 июля 2009

malloc для выделения памяти. num + 1 разрешает использовать нулевой терминатор - \0.

10 голосов
/ 01 августа 2009

Преамбула: я не могу в это поверить! Я был озадачен таким выражением, когда меня учили основам Си (без каламбура). Вот почему я углубляюсь в подробности в разделе «Анализ кода».

Разбор кода

Первая проблема - парсинг кода

Добро пожаловать в сумеречную зону

str = (char *) malloc (sizeof(char) * (num+1));

При работе с C / C ++ синтаксический анализ этого вида выражения является обязательным, поэтому мы разбим его на его компоненты. Первое, что мы видим здесь, это что-то вроде:

variable = (expression) function (expression) ;

Когда я впервые увидел это, я просто сказал: «Эй, я не могу поверить, что есть язык программирования, где вы можете вызывать функцию, помещая ее параметры слева и справа от вызова функции!».

Разбор этой строки кода?

По правде говоря, эту строку следует читать так:

variable = function_a (function_b (expression)) ;

где:

expression is sizeof(char) * (num+1)
function_b is malloc
function_a is a cast operator

Оператор приведения C немного меньше естественного

Как уже объяснялось в другом месте, оператор приведения в стиле C больше похож на

(function_a) expression

чем естественнее

function_a(expression)

Что объясняет странность всей строки кода.

Есть ли в C ++ что-то более понятное?

Обратите внимание, что в C ++ вы можете использовать обе нотации, но вместо них вы должны использовать static_cast, const_cast, reinterpret_cast или dynamic_cast вместо вышеуказанных нотаций. При использовании C ++ приведенная выше строка кода будет выглядеть так:

str = static_cast<char *> ( malloc (sizeof(char) * (num+1))  ) ;

Мой размер больше вашего

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

Итак, если вы напишите:

size_t i = sizeof(char) ;
size_t j = sizeof(int) ;

Вероятно, у вас (в 32-битном Linux) будет значение 1 для i и 4 для j. Его использование в malloc похоже на выражение «я хочу достаточно места, чтобы разместить 25 автомобилей длиной 4 метра» вместо «я хочу хотя бы 100 метров».

Что-то есть в Маллоке

Параметр Malloc - это size_t, то есть целое число без знака. Вы даете ему размер в байтах, и в случае успеха он возвращает вам адрес выделенной памяти, достаточно большой для использования в качестве массива. Например:

int * p = (int *) malloc (25 * sizeof(int)) ;

Тогда p указывает на память, где вы можете поместить 25 целых чисел рядом, как будто внутри массива, индексы которого идут от нуля до размера minux один. Например:

p[0] = 42 ;  // Ok, because it's the 1st item of the array
p[24] = 42 ; // Ok, because it's the 25th item of the array
p[25] = 42 ; // CORRUPTION ERROR, because you are trying to
             // use the 26th item of a 25 items array !

Примечание: у вас тоже есть арифметика с указателями, но это выходит за рамки вопроса.

число + 1?

Строки в стиле C несколько отличаются от строк других языков. Каждый символ строки может иметь любое значение, НО НЕ НОЛЬ. Поскольку ноль (также отмеченный \ 0) отмечает конец строки c.

Другими словами: вы никогда не узнаете размер c-строки, но, выполнив поиск символа \ 0, вы сможете узнать, где он заканчивается (кстати, это одна из причин переполнения буфера и повреждения стека).

Например, строка «Hello» имеет 5 символов:

"Hello" seems to be an array containing 'H', 'e', 'l', 'l' and 'o'.

Но по правде говоря, он имеет 6 символов, последний из которых - символ ZERO, который отмечается с помощью escape-символа \ 0. Таким образом:

"Hello" is an array containing 'H', 'e', 'l', 'l', 'o' and 0.

Это объясняет, что когда вы хотите выделить достаточно места для строки из «num» символов, вы выделяете вместо «num + 1» символы.

7 голосов
/ 31 июля 2009

malloc выделяет память.

num + 1 as num - количество символов в строке и +1 для нулевого терминатора

2 голосов
/ 31 июля 2009

Malloc в этом случае выделяет num + 1 раз размер (char) байтов. Это стандартная практика, когда вы хотите выделить массив элементов. Символ в sizeof (char) обычно заменяется типом выделяемого массива.

Строго говоря, в этом примере размер size (char) не является обязательным. Он гарантированно будет размером 1 по стандарту C и, следовательно, просто умножится на 1.

1 голос
/ 31 июля 2009

Malloc выделяет память, в данном случае для строки str длины num. (char *) - это тип для str sizeof (char) - количество байтов, необходимое для каждого символа. +1 для завершающего нулевого символа в строке, обычно ноль.

1 голос
/ 31 июля 2009

malloc выделяет массив char (в данном случае) в куче.

массив будет иметь длину num + 1, но самая длинная строка, которую он может содержать, имеет длину 'num', поскольку строка в Cнужен завершающий нулевой байт.

0 голосов
/ 31 июля 2009
sizeof(char)

безопасно. Не следует использовать один байт на символ.

Мой вопрос: что вы делаете, программируя, если не знаете, что делает malloc?

man malloc

в системе Linux. На винде. кто знает? Вероятно, 17 щелчков мыши.

0 голосов
/ 31 июля 2009

malloc выделяет память из кучи и возвращает указатель на нее. Это полезно, когда вы не знаете, сколько памяти вам понадобится во время компиляции.

Что касается того, почему (num + 1), это действительно зависит от того, что делает код ... возможно, num - это количество символов в строке, а +1 - для завершающего байта NUL. Я не знаю, для чего будет sizeof (char) в этом случае.

0 голосов
/ 31 июля 2009

Этот код пытается выделить часть памяти, которая может содержать num + 1 значения типа char. Поэтому, если чат равен одному байту, а num равно 10, он попытается выделить 11 байтов памяти и вернуть указатель на эту память.

+ 1, вероятно, используется, потому что программист хотел сохранить строку (массив символов) из num символов и нуждается в дополнительном символе для хранения завершающего символа \ 0 (null). В C / C ++. Строки chracater по соглашению заканчиваются нулевым символом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...