Каков эквивалент нового/удалять из C++ в C?

Каков эквивалент нового/удалять из C++ в C?

Или это - то же в C/C++?

27
задан Brian Tompsett - 汤莱恩 6 July 2015 в 19:36
поделиться

5 ответов

В Си нет выражения new/delete.

Ближайшим эквивалентом являются функции 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;
46
ответ дан 28 November 2019 в 04:42
поделиться

Не является точной копией, но совместимые эквиваленты являются 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
3
ответ дан 28 November 2019 в 04:42
поделиться

Обратите внимание, что в C++ конструкторы могут бросать исключения. Эквивалент player* p = new player(); в Си был бы примерно таким.

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);
7
ответ дан 28 November 2019 в 04:42
поделиться

Использование new и delete в C++ сочетает в себе две обязанности - выделение/освобождение динамической памяти и инициализацию/освобождение объекта.

Как говорится во всех других ответах, наиболее распространенным способом выделения и освобождения динамической памяти является вызов 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, тогда как если библиотека обрабатывает как выделение, так и инициализацию, клиенту не нужно знать размер типа, таким образом, реализация может варьироваться без изменения клиента вообще. Ни один из них не вводит столько связей между клиентом и реализацией, как C++. (Часто лучше думать о C++ как о языке метапрограммирования шаблонов с vtables, чем о языке OO)

6
ответ дан 28 November 2019 в 04:42
поделиться

Используйте функции malloc / free.

2
ответ дан 28 November 2019 в 04:42
поделиться