Что эквивалентно новому/удалению С++ в C?
Что эквивалентно новому/удалению С++ в C?
Или это то же самое в C/С++?
Ответы
Ответ 1
Нет выражения new
/delete
в C.
Ближайшим эквивалентом являются malloc
и free
функции, если вы игнорируете конструкторы/деструкторы и сохраняете безопасность.
#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;
Ответ 2
Обратите внимание, что конструкторы могут генерировать исключения в С++. Эквивалент 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);
Ответ 3
Использование new
и delete
в С++ сочетает в себе две обязанности - распределение/освобождение динамической памяти и инициализацию/освобождение объекта.
Как говорят все остальные ответы, наиболее распространенным способом выделения и выпуска динамической памяти является вызов malloc
и free
. Вы также можете использовать функции, специфичные для ОС, для получения большого объема памяти и выделения в ней объектов, но это реже - только если у вас есть довольно специфические требования, которые malloc не удовлетворяет.
В C большинство API-интерфейсов предоставят пару функций, которые выполняют другие роли new
и delete
.
Например, файл api использует пару открытых и закрытых функций:
// 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-интерфейсы предоставляют функции, которые просто выполняют инициализацию и освобождают часть контракта, что эквивалентно конструктору и деструктору, что позволяет клиентскому коду использовать либо автоматическое, статическое, либо динамическое хранилище. Одним из примеров является API pthreads:
pthread_t thread;
pthread_create( &thread, NULL, thread_function, (void*) param);
Это позволяет клиенту более гибко, но увеличивает связь между библиотекой и клиентом - клиенту необходимо знать размер типа pthread_t
, тогда как если библиотека обрабатывает как распределение, так и инициализацию, клиенту не нужно знать размер типа, поэтому реализация может изменяться без изменения клиента вообще. Ничто не добавляет столько взаимодействия между клиентом и реализацией, как это делает С++. (Часто лучше думать о С++ как языке метапрограммирования шаблона с vtables, чем язык OO)
Ответ 4
Непосредственно точная копия, но совместимые эквиваленты являются 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
Ответ 5
Использовать функции malloc/free.