2010-05-15 7 views

ответ

32

Там нет 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; 
+2

* @ KennyTM: * Выполняет ли 'sizeof (* p)' фактически разыменование 'p' или полностью эквивалентно записи' SizeOf (INT) '? Похоже, что в первом случае это выражение потенциально может вызвать ошибку сегментации (поскольку на данный момент 'p' еще не назначена). В последнем случае я, вероятно, по-прежнему предпочитаю писать 'sizeof (int)', потому что есть меньше возможностей для непонимания того, что делает этот оператор. – stakx

+5

@stakx: Оператор 'sizeof' оценивается во время компиляции. Там нет разыменования. 'sizeof (* p)' предпочтительнее 'sizeof (int)', потому что если вы измените тип 'p' на' double', компилятор не сможет предупредить вас о несоответствии размера. – kennytm

+8

@stakx Оператор 'sizeof' - это отображение от ** type ** до' size_t'. ** значение ** его операнда совсем не интересно. Например, в 'sizeof (1 + 2)' абсолютно нет необходимости вычислять результат '3'. Оператор 'sizeof' просто видит выражение типа' int + int' и указывает, что результатом также является 'int'. Затем он отображает 'int' в 4 (или 2 или 8, в зависимости от платформы). Это то же самое с 'sizeof (* p)'. Система типов знает, что на уровне типа разыменование 'int *' дает 'int'. 'sizeof' вообще не интересуется значением' * p', имеет значение только тип. – fredoverflow

3

Неточная точная копия, но совместимые эквиваленты являются 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 
+4

В C вам не нужно бросать из void * в другие указатели. Его просто int * p = malloc (sizeof (int) * cElements); –

+0

Крис: Ты уверен? Я не работал с C уже довольно давно, но IIRC, я должен был это сделать, потому что возвращаемый тип malloc недействителен *. –

+0

В c 'void *' автоматически преобразуется в другие типы указателей. Выдача возврата malloc может привести к ошибкам, если вы не включили 'stdlib.h', поскольку параметры будут считаться' int'. –

2

Используйте таНос/свободные функции.

6

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

Как выглядит 'construct_player'? –

5

Использование 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)

+0

Можете ли вы объяснить, какие именно требования malloc не удовлетворяют? – Pacerier

+0

@Pacerier 'malloc' выделяет память. 'operator new' (обычно) выделяет память * и * инициализирует память, чтобы содержать значения, предоставленные конструктором указанного класса объекта. (существует переменная 'operator new', называемая« размещение new », которая не выделяет память, поэтому вы можете использовать malloc для первой части, а новый для второго, если хотите) –

Смежные вопросы