2010-05-15 26 views

cevap

32

, yakın eşdeğer malloc and free functions olan C

hiçbir new/delete ifadesi var.

#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: * '' '' '' ('p)' aslında dereferans 'p' yapar mı, yoksa tam olarak yazmaya eşdeğer midir? sizeof (int) '? Önceki durumda, bu ifadenin potansiyel olarak bir segmentasyon hatasına neden olacağı düşünülmektedir (çünkü bu noktada henüz 'p' atanmamıştır). İkinci durumda, muhtemelen “sizeof (int)” yazmayı tercih ederim, çünkü bu ifadenin yanlış anlama olasılığı daha azdır. – stakx

+5

@stakx: "sizeof" operatörü derleme zamanında değerlendirilir. Hata yok. 'sizeof (* p)', '' '' inden (int) 'ye tercih edilir, çünkü eğer 'p'' 'double' türünü değiştirirseniz, derleyici size boyut uyuşmazlığı konusunda uyarıda bulunamaz. – kennytm

+8

@stakx 'sizeof' operatörünün ** tip ** ile' size_t' arasında bir eşlemesi var. İşleneninin ** değeri ** hiç de ilginç değil. Örneğin, 'sizeof (1 + 2)' de, '3' sonucunu hesaplamaya gerek yoktur. "Sizeof" operatörü, int + int türünde bir ifadeyi görür ve sonucun da bir "int" olduğunu gösterir. Daha sonra 4'e (ya da platforma bağlı olarak 2 ya da 8) int 'eşleştirir. Aynı şey ile aynı şeydir (* p). Tip sistem, tip seviyesinde, int '' int * '' 'nın bir int' olduğunu belirtir. 'sizeof'' 'p''nın değeriyle ilgilenmez, sadece tip önemlidir. – fredoverflow

3

Doğrudan bir tam kopya değil, eşdeğer eşdeğerleri malloc ve ücretsizdir.

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

yok kurucular/yok ediciler - yine de onları yok C :)

bellek boyutu elde etmek için, sizeof operatörünü kullanabilirsiniz.

Eğer çok boyutlu diziler ile çalışmak isterseniz, (yeni gibi) burayı defalarca kullanmak gerekir:

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'de void * 'den diğer işaretçilere yayınlamanız gerekmez. Onun sadece int * p = malloc (büyüklük (int) * cElements); –

+0

Chris: Emin misin? C ile uzun zamandır çalışmıyorum ama IIRC, bunu yapmak zorundaydım çünkü mallocun geri dönüşü geçersizdi *. –

+0

c 'void *' otomatik olarak diğer işaretçi türlerine dönüştürür. Eğer parametreler 'int' olarak kabul edilmiş gibi' stdlib.h' dahil etmediyseniz malloc iadesinin döndürülmesi hatalara neden olabilir. –

2

Kullanım malloc/ücretsiz fonksiyonlar.

6

Yapıcılar C++ 'da istisnalar atabileceğini unutmayın. yıkıcılar "atmak" asla gerektiği, çünkü player* p = new player(); eşdeğer, 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 eşdeğer basittir böyle bir şey olurdu. C++ new ve delete ait

destruct(p); 
free(p); 
+0

'build_player' neye benziyordu? –

5

Kullanım iki sorumluluk birleştirir - tahsis/dinamik bellek bırakmadan ve başlatılıyor/Bir nesneyi bırakmadan.

Diğer tüm yanıtlarda da belirtildiği gibi, dinamik belleği ayırmanın ve serbest bırakmanın en yaygın yolu malloc ve free numaralı telefonu çağırmaktır. Ayrıca, belleğe büyük bir parça almak ve nesnelerinizi buna ayırmak için OS'ye özgü işlevleri kullanabilirsiniz, ancak bu daha nadirdir - yalnızca malloc'un tatmin etmediği özel gereksinimleriniz varsa. C, çoğu API, new ve delete'un diğer rollerini yerine getiren bir çift işlev sunacaktır.

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

Bu fopenFILE yapısı için alanı ayırmak için malloc kullandığı olabilir, ya da statik olarak bir tablo tahsis edebilir:

Örneğin

, dosya API açık ve kapalı fonksiyonların bir çift kullanır işlem başlangıcında maksimum dosya tanıtıcısı sayısı. Önemli olan, API'nın istemciyi malloc ve free kullanmasını gerektirmez.

Diğer API'lar, yalnızca sözleşmenin bir kısmını ilklendirmeyi ve serbest bırakmayı gerçekleştiren işlevler sağlar - istemci kodunun otomatik, statik veya dinamik depolamayı kullanmasına izin veren yapıcıya ve yıkıcıya eşdeğerdir.Bir örnek PThreads API: Bu istemci daha fazla esneklik sağlar

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

ancak kütüphane ve müşteri arasındaki bağlantıyı arttıran - kitaplığı iki işleme durumunda ise müşteri, pthread_t türü boyutunu bilmelidir tahsisi ve ilklendirmesi, müşterinin türün büyüklüğünü bilmesine gerek olmadığı için, uygulama müşteriyi hiç değiştirmeden değişebilir. İstemci ile C++ gibi uygulama arasında ne kadar bir eşleştirme yapılmaz. (C++ 'yı bir OO dili yerine vtables ile bir şablon metaprogramlama dili olarak düşünmek daha iyidir.)

+0

Malloc'un hangi gereksinimleri karşılayamadığını tam olarak açıklayabilir misiniz? – Pacerier

+0

@Pacerier 'malloc' hafızayı ayırır. “new” operatörü (genellikle) bellek ayırır * ve * belirtilen nesne sınıfının yapıcısı tarafından sağlanan değerleri içerecek şekilde belleği başlatır. (bellek ayırmayan 'yeni yerleştirme' adı verilen bir işleç değişkeni var, böylece ilk bölüm için malloc kullanabilir ve dilerseniz ikinci için yeni olabilir) –