Что эквивалентно новому/удалению C++ в C?Что эквивалентно новому/удалению C++ в C?
Или это то же самое в C/C++?
Что эквивалентно новому/удалению C++ в C?Что эквивалентно новому/удалению C++ в C?
Или это то же самое в C/C++?
Там нет new
/delete
выражения в С.
Ближайший эквивалентом является malloc
and free
functions, если игнорировать конструктор/деструкторы и безопасность типа.
#include <stdlib.h>
int* p = malloc(sizeof(*p)); // int* p = new int;
...
free(p); // delete p;
int* a = malloc(12*sizeof(*a)); // int* a = new int[12];
...
free(a); // delete[] a;
Неточная точная копия, но совместимые эквиваленты являются malloc и бесплатными.
<data-type>* variable = (<data-type> *) malloc(memory-size);
free(variable);
Нет конструкторов/деструкторов - C в любом случае их не имеет :)
Чтобы получить память-размер, вы можете использовать sizeof
оператора.
Если вы хотите работать с многомерными массивами, вам нужно будет использовать его несколько раз (как новый):
int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12.
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc
В C вам не нужно бросать из void * в другие указатели. Его просто int * p = malloc (sizeof (int) * cElements); –
Крис: Ты уверен? Я не работал с C уже довольно давно, но IIRC, я должен был это сделать, потому что возвращаемый тип malloc недействителен *. –
В c 'void *' автоматически преобразуется в другие типы указателей. Выдача возврата malloc может привести к ошибкам, если вы не включили 'stdlib.h', поскольку параметры будут считаться' int'. –
Используйте таНос/свободные функции.
Обратите внимание, что конструкторы могут исключать исключения из C++. Эквивалент player* p = new player();
будет что-то подобное в C.
struct player *p = malloc(sizeof *p);
if (!p) handle_out_of_memory();
int err = construct_player(p);
if (err)
{
free(p);
handle_constructor_error();
}
эквивалент delete p
проще, потому что деструкторы никогда не должны «бросить».
destruct(p);
free(p);
Как выглядит 'construct_player'? –
Использование new
и delete
в C++ объединяет в себе две ответственности - отведение/отпускании динамической памяти и инициализация/отпускание объекта.
Как и все другие ответы, наиболее распространенным способом распределения и освобождения динамической памяти является вызов malloc
и free
. Вы также можете использовать специфичные для ОС функции, чтобы получить большой кусок памяти и выделять в нем свои объекты, но это реже - только если у вас есть довольно специфические требования, которые malloc не удовлетворяет.
В C большинство API-интерфейсов предоставят пару функций, которые выполняют другие функции new
и delete
.
Например, файл апи использует пару открытых и закрытых функций:
// C++
fstream* fp = new fstream("c:\\test.txt", "r");
delete fp;
// C
FILE *fp=fopen("c:\\test.txt", "r");
fclose(fp);
Это может быть, что fopen
использует malloc
выделить память для FILE
структуры, или он может статически выделить таблицу для максимальное количество указателей файлов при запуске процесса. Дело в том, что API не требует от клиента использования malloc
и free
.
Другие API-интерфейсы предоставляют функции, которые просто выполняют инициализацию и освобождают часть контракта, что эквивалентно конструктору и деструктору, что позволяет клиентскому коду использовать либо автоматическое, статическое, либо динамическое хранилище.Одним из примеров является Pthreads API:
pthread_t thread;
pthread_create(&thread, NULL, thread_function, (void*) param);
Это позволяет клиенту большую гибкость, но и увеличивает сцепление между библиотекой и клиентом - клиент должен знать размер pthread_t
типа, в то время как если библиотека обрабатывает как распределения и инициализации клиент не должен знать размер типа, поэтому реализация может изменяться без изменения клиента вообще. Ничто не добавляет столько взаимодействия между клиентом и реализацией, как это делает C++. (Часто лучше думать о C++ в качестве языка метапрограммирования шаблона с использованием vtables, чем язык OO)
Можете ли вы объяснить, какие именно требования malloc не удовлетворяют? – Pacerier
@Pacerier 'malloc' выделяет память. 'operator new' (обычно) выделяет память * и * инициализирует память, чтобы содержать значения, предоставленные конструктором указанного класса объекта. (существует переменная 'operator new', называемая« размещение new », которая не выделяет память, поэтому вы можете использовать malloc для первой части, а новый для второго, если хотите) –
* @ KennyTM: * Выполняет ли 'sizeof (* p)' фактически разыменование 'p' или полностью эквивалентно записи' SizeOf (INT) '? Похоже, что в первом случае это выражение потенциально может вызвать ошибку сегментации (поскольку на данный момент 'p' еще не назначена). В последнем случае я, вероятно, по-прежнему предпочитаю писать 'sizeof (int)', потому что есть меньше возможностей для непонимания того, что делает этот оператор. – stakx
@stakx: Оператор 'sizeof' оценивается во время компиляции. Там нет разыменования. 'sizeof (* p)' предпочтительнее 'sizeof (int)', потому что если вы измените тип 'p' на' double', компилятор не сможет предупредить вас о несоответствии размера. – kennytm
@stakx Оператор 'sizeof' - это отображение от ** type ** до' size_t'. ** значение ** его операнда совсем не интересно. Например, в 'sizeof (1 + 2)' абсолютно нет необходимости вычислять результат '3'. Оператор 'sizeof' просто видит выражение типа' int + int' и указывает, что результатом также является 'int'. Затем он отображает 'int' в 4 (или 2 или 8, в зависимости от платформы). Это то же самое с 'sizeof (* p)'. Система типов знает, что на уровне типа разыменование 'int *' дает 'int'. 'sizeof' вообще не интересуется значением' * p', имеет значение только тип. – fredoverflow