Что является эквивалентом нового / удаления C ++ в C? - PullRequest
24 голосов
/ 15 мая 2010

Что является эквивалентом нового / удаления C ++ в C?

Или то же самое в C / C ++?

Ответы [ 5 ]

43 голосов
/ 15 мая 2010

Нет выражения 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;
7 голосов
/ 15 мая 2010

Обратите внимание, что конструкторы могут генерировать исключения в 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);
6 голосов
/ 15 мая 2010

Использование 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, чем оо-языке)

3 голосов
/ 15 мая 2010

Непосредственно точная копия, но совместимые эквиваленты являются 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
2 голосов
/ 15 мая 2010

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

...