Вы немного сбиваете с толку. Я' не знаю, перепутываете ли Вы некоторые понятия.
у Вас нет виртуального базового класса в Вашем OP. У Вас просто есть базовый класс.
Вы сделали виртуальное наследование. Это обычно используется во множественном наследовании так, чтобы несколько производных классов использовали членов базового класса, не воспроизводя их.
базовый класс А с чистой виртуальной функцией не быть инстанцированным. это требует синтаксиса, который достигает Paul. Это обычно используется так, чтобы производные классы определили те функции.
я не хочу объяснять больше об этом, потому что я не полностью получаю то, что Вы спрашиваете.
malloc
предназначен для выделения памяти.
num + 1
разрешает использование ограничителя нуля - \ 0
.
malloc выделяет память.
num + 1 , поскольку num - это количество символов в строке, а +1 для нулевого терминатора
malloc выделяет массив символов (в данном случае) в куче.
массив будет иметь длину num + 1, но самая длинная строка, которую он может содержать, - это длина num, потому что строке в C нужен конечный нулевой байт.
malloc
- это функция , которая выделяет часть памяти в куче и возвращает на нее указатель . Он похож на оператор new
во многих языках. В этом случае он создает блок памяти, который может существовать в течение произвольного периода времени и иметь произвольный размер. Это само по себе является довольно подробным материалом, который довольно сложно объяснить и требует отдельного вопроса.
num + 1
компенсирует нулевой терминатор в конце струны. Строкам часто нужно знать свою длину, и традиция C заключается в том, чтобы выделять место для дополнительного символа в конце строки, которым всегда будет специальный символ \ 0
. Это позволяет функциям, работающим со строкой, автоматически определять размер строки. Например, если вы хотите что-то сделать с каждым символом строки, не зная, какой длины строка, вы можете сделать что-то вроде этого:
const char *ptr = str;
while (*ptr != '\0') {
process(*ptr);
ptr++;
}
Malloc - это вызов для выделения памяти.
Приведенный выше код будет выделять пространство для num + 1 символов. Вероятно, есть строка с числом символов, и автор кода добавил место для нулевого терминатора.
После вызова str будет указывать на начало того блока памяти, который был выделен.
Этот код пытается выделить часть памяти, которая может содержать num + 1 значений типа char. Таким образом, если чат равен одному байту, а число равно 10, он попытается выделить 11 байтов памяти и вернуть указатель на эту память.
+1, вероятно, используется, потому что программист хотел сохранить строку (массив символов) из числа символов и нуждается в дополнительном символе для хранения завершающего символа '\ 0' (нулевого). В C / C ++. Строки chracater по соглашению заканчиваются нулевым символом.
Malloc в этом случае выделяет число + 1 байт, умноженное на sizeof (char). Это стандартная практика, когда вы хотите выделить массив элементов. Символ в sizeof (char) обычно заменяется типом выделяемого массива.
Строго говоря, в этом примере sizeof (char) не требуется. По стандарту C он гарантированно имеет размер 1 и, следовательно, просто умножается на 1.
malloc выделяет память из кучи и возвращает указатель на нее. Это полезно, когда вы не знаете, сколько памяти вам понадобится во время компиляции.
Что касается того, почему (num + 1), это действительно зависит от того, что делает код ... возможно, num - это количество в строке, а +1 для байта терминатора NUL в конце. Однако я не знаю, для чего в этом случае будет использоваться sizeof (char).
sizeof(char)
безопасен. Не следует предполагать, что на каждый символ приходится один байт.
Мой вопрос: что вы программируете, если не знаете, что делает malloc?
man malloc
в системе Linux. В Windows. кто знает? Наверное, 17 щелчков мышью.
Преамбула: Не могу поверить! Я был сбит с толку таким выражением, когда меня учили основам Си (без каламбура). Вот почему я очень подробно описываю раздел «синтаксический анализ кода».
Первая проблема - это синтаксический анализ кода
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 больше похож на
(function_a) expression
, чем на более естественный
function_a(expression)
, что объясняет странность всей строки кода.
Обратите внимание, что в C ++ вы можете использовать обе нотации, но вместо них следует использовать static_cast, const_cast, reinterpret_cast или dynamic_cast вместо обозначений выше. Используя преобразование C ++, приведенная выше строка кода будет выглядеть так:
str = static_cast<char *> ( malloc (sizeof(char) * (num+1)) ) ;
sizeof - оператор. Вы можете думать об этом как о функции, работающей с типами.
Обратите внимание, что в C ++ вы можете использовать обе нотации, но вместо них следует использовать static_cast, const_cast, reinterpret_cast или dynamic_cast вместо обозначений выше. Используя преобразование C ++, приведенная выше строка кода будет выглядеть так:
str = static_cast<char *> ( malloc (sizeof(char) * (num+1)) ) ;
sizeof - оператор. Вы можете думать об этом как о функции, работающей с типами.
Обратите внимание, что в 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 !
Примечание: у вас тоже есть арифметика указателей, но это выходит за рамки вопроса.
Строки в стиле C несколько отличаются от строк в других языках. Каждый символ строки может иметь любое значение, НО НЕ НУЛЬ. Поскольку ноль (также отмеченный как \ 0) отмечает конец строки ac.
Другими словами: вы никогда не знаете размер 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» символы.
Malloc выделяет память, в данном случае для строки str длины num. (char *) - это тип для str sizeof (char) - это количество байтов, необходимое для каждого символа. +1 означает завершающий нулевой символ в строке, обычно ноль.