Что эквивалентно новому/удалению С++ в 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.