Malloc sonucunu ald─▒m m─▒?


Al─▒nan cevaba git


Gelen bu soruya , birisi bir ├Ânerilen yorumun ─▒ gerekti─čini de─čil sonucunu d├Âk├╝m malloc , yani

 int *sieve = malloc(sizeof(int) * length);
 

ziyade:

 int *sieve = (int *) malloc(sizeof(int) * length);
 

Neden b├Âyle olsun ki?


2299









Cevap say─▒s─▒n─▒ say: 26






Hay─▒r ; E─čer yok ├ž├╝nk├╝ sonu├ž d├Âkme:

  • Bu durumda, void * herhangi bir di─čer i┼čaret├ži tipine otomatik ve g├╝venli bir ┼čekilde tan─▒t─▒ld─▒─č─▒ gibi, gereksizdir .
  • Kodda kar─▒┼č─▒kl─▒k ekler, yay─▒nlar─▒n okunmas─▒ kolay de─čildir (├Âzellikle i┼čaret├ži t├╝r├╝ uzunsa).
  • Kendini tekrar etmeni sa─člar, ki bu genellikle k├Ât├╝d├╝r.
  • Eklemeyi unuttuysan─▒z bir hatay─▒ gizleyebilir <stdlib.h> . Bu, ├ž├Âkmelere neden olabilir (veya daha da k├Ât├╝s├╝, kodun tamamen farkl─▒ bir b├Âl├╝m├╝nde daha sonraya kadar ├ž├Âkmeye neden olmaz ). ─░┼čaret├žiler ve tam say─▒lar─▒n farkl─▒ boyutlarda olmas─▒ durumunda ne olaca─č─▒n─▒ d├╝┼č├╝n├╝n; o zaman oyuncu se├žimi yaparak bir uyar─▒ gizliyorsunuz ve iade etti─činiz adresin bitlerini kaybedebilirsiniz. Not: C99'dan itibaren kapal─▒ fonksiyonlar C'den ayr─▒lm─▒┼čt─▒r ve bu nokta art─▒k ge├žerli de─čildir, ├ž├╝nk├╝ a├ž─▒klanmam─▒┼č fonksiyonlar─▒n geri d├Ând├╝─č├╝n├╝ otomatik bir varsay─▒m yoktur int .

Bir a├ž─▒klama olarak, not dedim, de─čil "sen yok "E─čer d├Âk├╝m yok" ihtiya├ž d├Âk├╝m i├žin". Bence do─čru yapsan─▒z bile oyuncu kadrosunu dahil etmek bir ba┼čar─▒s─▒zl─▒k. Bunu yapman─▒n faydas─▒ yok, ancak bir dizi potansiyel risk var ve al├ž─▒ dahil riskleri bilmedi─činizi g├Âsteriyor.

Ayr─▒ca, yorumcular─▒n belirtti─či gibi, yukar─▒dakilerin C ++ hakk─▒nda de─čil, C hakk─▒nda da konu┼čtu─čunu unutmay─▒n. C ve C ++ 'ya ayr─▒ diller oldu─čuna ├žok inan─▒yorum.

Daha fazla eklemek i├žin, kodunuz int hataya neden olabilecek tip bilgisi ( ) tekrarlar . ─░kisini birlikte "kilitlemek" i├žin d├Ân├╝┼č de─čerini saklamak i├žin kullan─▒lan i┼čaret├žiyi referanstan ├ž─▒karmak daha iyidir:

 int *sieve = malloc(length * sizeof *sieve);
 

Bu ayn─▒ zamanda length daha fazla g├Âr├╝n├╝rl├╝k i├žin ├Âne do─čru hareket eder ve gereksiz parantezleri d├╝┼č├╝r├╝r sizeof ; yaln─▒zca arg├╝man bir t├╝r ad─▒ oldu─čunda gerekli olurlar . Pek ├žok insan kodunu daha ayr─▒nt─▒l─▒ hale getiren bu durumu bilmiyor veya g├Ârmezden geliyor gibi g├Âr├╝n├╝yor. Unutmay─▒n: sizeof bir fonksiyon de─čil! :)


Ta┼č─▒rken length ├Âne olabilecek baz─▒ nadir durumlarda g├Âr├╝n├╝rl├╝─č├╝n├╝ art─▒rmak, bir de genel durumda, olarak ifade yazmak daha iyi olmas─▒ gerekti─čini dikkat etmelidir:

 int *sieve = malloc(sizeof *sieve * length);
 

─░lkinde tutuldu─čundan beri sizeof , bu durumda, ├žarpma i┼čleminin en az size_t matematikle yap─▒lmas─▒n─▒ sa─člar .

Kar┼č─▒la┼čt─▒rma: malloc(sizeof *sieve * length * width) vs malloc(length * width * sizeof *sieve) ikinci length * width ne zaman ta┼čabilir width ve length ondan daha k├╝├ž├╝k tiplerdir size_t .


2120







C 'nin geri d├Ân├╝┼č de─čerini kullanman─▒za gerek yoktur malloc . Taraf─▒ndan d├Ând├╝r├╝len ge├žersiz i┼čaret├ži malloc , otomatik olarak do─čru t├╝re d├Ân├╝┼čt├╝r├╝l├╝r. Ancak, kodunuzun bir C ++ derleyicisi ile derlenmesini istiyorsan─▒z, al├ž─▒ya ihtiya├ž vard─▒r. Topluluk aras─▒nda tercih edilen bir alternatif a┼ča─č─▒dakileri kullanmakt─▒r:

 int *sieve = malloc(sizeof *sieve * length);
 

Ayr─▒ca, t├╝r├╝n├╝ de─či┼čtirirseniz, ifadenin sa─č taraf─▒n─▒ de─či┼čtirmek konusunda endi┼čelenmenize gerek kalmaz sieve .

─░nsanlar─▒n belirtti─či gibi, yay─▒nlar k├Ât├╝d├╝r. ├ľzel i┼čaret├ži atmalar─▒n─▒.


357







Sen yok , d├Âkme, ├ž├╝nk├╝:

  • Kodunuzu C ve C ++ aras─▒nda daha ta┼č─▒nabilir hale getirir ve SO deneyiminin g├Âsterdi─či gibi, bir├žok programc─▒ ger├žekten C ++ (veya C art─▒ yerel derleyici uzant─▒lar─▒) yazarken C'ye yazd─▒klar─▒n─▒ iddia eder.
  • Aksi halde bir hata gizleyebilirsiniz : notu yazmak i├žin zaman kafa kar─▒┼čt─▒r─▒c─▒ t├╝m SO ├Ârnekleri type * kar┼č─▒ type ** .
  • Sizi #include uygun bir ba┼čl─▒k dosyas─▒nda ba┼čar─▒s─▒z oldu─čunuzu fark etmekten al─▒koyma fikri a─ča├žlar i├žin orman─▒ ├Âzl├╝yor . "Derleyiciden prototipleri g├Ârmeme konusunda ┼čikayet etmesini istemedi─činiz konusunda endi┼čelenmeyin - bu sinir bozucu stdlib.h, hat─▒rlanmas─▒ gereken GER├çEK ├Ânemli bir ┼čey!"
  • Ekstra bir bili┼čsel ├žapraz kontrol├╝ zorlar . (─░ddia edilen) istenen t├╝r├╝, bu de─či┼čkenin ham boyutu i├žin yapt─▒─č─▒n─▒z aritmeti─čin yan─▒na yerle┼čtirir. ─░ddiaya girerim malloc() bir al├ž─▒ oldu─čunda b├Âceklerin daha h─▒zl─▒ yakaland─▒─č─▒n─▒ g├Âsteren bir SO ├žal─▒┼čmas─▒ yapabilirsin . ─░ddialarda oldu─ču gibi, niyetini ortaya ├ž─▒karan a├ž─▒klamalar hatalar─▒ azalt─▒r.
  • Makine kontrol edebilirsiniz ┼čekilde kendini tekrar genellikle oldu─ču harika bir fikir. Asl─▒nda, iddia budur ve al├ž─▒ bu kullan─▒m─▒ bir iddiad─▒r. Turing, uzun y─▒llar ├Ânce fikir ├╝retti─činden, iddialar hala kodu do─črulamak i├žin sahip oldu─čumuz en genel tekniktir.

333







Di─čer belirtildi─či gibi, C i├žin de─čil, C ++ i├žin gerekli de─čildir. C kodunuzu bir C ++ derleyicisi ile derleyece─činizi d├╝┼č├╝n├╝yorsan─▒z, bunun nedenlerinden dolay─▒ bir makro kullanabilirsiniz:

 #ifdef __cplusplus
# define NEW(type, count) ((type *)calloc(count, sizeof(type)))
#else
# define NEW(type, count) (calloc(count, sizeof(type)))
#endif
 

Bu ┼čekilde hala ├žok kompakt bir ┼čekilde yazabilirsiniz:

 int *sieve = NEW(int, 1);
 

ve C ve C ++ i├žin derleyecektir.


163







G├Ânderen Vikipedi :

D├Âk├╝m avantajlar─▒

  • Al├ž─▒ dahil etmek, bir C program─▒n─▒n veya fonksiyonunun C ++ olarak derlenmesine izin verebilir.

  • D├Âk├╝m, 1989'dan ├Ânce, asl─▒nda bir karakter d├Ând├╝ren malloc s├╝r├╝mleri i├žin izin veriyor.

  • D├Âk├╝m, geli┼čtiricinin t├╝r i┼čaretleme t├╝r├╝ndeki tutars─▒zl─▒klar─▒ tespit etmesine yard─▒mc─▒ olabilir, ├Âzellikle i┼čaret├ži malloc () ├ža─čr─▒s─▒ndan uza─ča bildirilirse (i┼čaret├ži gerekmeden modern derleyiciler ve statik analiz├Ârler b├Âyle bir davran─▒┼č─▒ uyarsa da)

D├Âk├╝m dezavantajlar─▒

  • ANSI C standard─▒na g├Âre, d├Âk├╝m gereksizdir.

  • Oyuncular eklemek, malloc i├žin prototipin bulundu─ču stdlib.h ba┼čl─▒─č─▒n─▒ i├žermemeyi maskeleyebilir . Malloc i├žin bir prototip yoklu─čunda, standart, C derleyicisinin malloc'un bir int d├Ând├╝rd├╝─č├╝n├╝ varsaymas─▒n─▒ gerektirir. Oyuncular yoksa, bu tamsay─▒ i┼čaret├žiye atand─▒─č─▒nda bir uyar─▒ verilir; ancak, oyuncularla birlikte, bu uyar─▒ ├╝retilmez ve bir hatay─▒ gizler. Baz─▒ mimarilerde ve veri modellerinde (uzun ve i┼čaret├žilerin 64-bit ve int'nin 32-bit oldu─ču 64-bit sistemlerdeki LP64 gibi), bu hata asl─▒nda tan─▒ms─▒z davran─▒┼ča neden olabilir; bit de─čeri, ger├žekte tan─▒mlanm─▒┼č i┼člev 64 bitlik bir de─čer verir. Arama kurallar─▒na ve bellek d├╝zenine ba─čl─▒ olarak, bu y─▒─č─▒n y─▒─č─▒lmas─▒na neden olabilir. Bu sorunun modern derleyicilerde farkedilmemesi daha az muhtemeldir, ├ž├╝nk├╝ bildirilmemi┼č bir fonksiyonun kullan─▒ld─▒─č─▒na dair uyar─▒lar ├╝retiyorlar, bu y├╝zden bir uyar─▒ g├Âr├╝nmeye devam edecek. ├ľrne─čin, GCC'nin varsay─▒lan davran─▒┼č─▒, alman─▒n mevcut olup olmad─▒─č─▒na bak─▒lmaks─▒z─▒n "yerle┼čik i┼člevin uyumsuz ├Ârt├╝k beyan─▒n─▒" okuyan bir uyar─▒ g├Âstermektir.

  • ─░┼čaret├žinin t├╝r├╝ bildirgesinde de─či┼čtirilirse, bir de malloc'un ├ža─čr─▒ld─▒─č─▒ ve at─▒ld─▒─č─▒ t├╝m sat─▒rlar─▒ de─či┼čtirmeniz gerekebilir.

Her ne kadar d├Âk├╝msiz malloc tercih edilirse ve ├žo─ču deneyimli programc─▒ bunu se├žse de, sorunlardan haberdar olmak i├žin hangisini kullanmal─▒s─▒n─▒z.

├ľrne─čin: C program─▒n─▒ C ++ olarak derlemeniz gerekiyorsa (ayr─▒ bir dil olmas─▒na ra─čmen) kullan─▒m sonucunu kullanmal─▒s─▒n─▒z malloc .


127







C'de bir bo┼čluk g├Âstergesini herhangi bir i┼čaretleyiciye dolayl─▒ olarak d├Ân├╝┼čt├╝rebilirsiniz, bu nedenle al├ž─▒ kullanmak gerekmez. Birini kullanmak, ge├žici g├Âzlemciye, birinin ihtiya├ž duyulmas─▒n─▒n bir yan─▒lt─▒c─▒ olabilece─činin bir nedeni oldu─čunu d├╝┼č├╝nebilir.


101







Malloc'un sonucunu kullanmazs─▒n─▒z, ├ž├╝nk├╝ b├Âyle yapmak kodunuza anlams─▒z karma┼ča katar.

─░nsanlar─▒n malloc sonucu almas─▒n─▒n en yayg─▒n nedeni, C dilinin nas─▒l ├žal─▒┼čt─▒─č─▒ndan emin olmad─▒klar─▒d─▒r. Bu bir uyar─▒ i┼čareti var: Belirli bir dil mekanizmas─▒ ├žal─▒┼č─▒r, o zaman nas─▒l bilmiyorsan─▒z yok bir tahminde bulun. Bak ya da Stack Overflow'a sor.

Baz─▒ yorumlar:

  • Bir bo┼č i┼čaret├ži, a├ž─▒k bir d├Âk├╝m olmadan ba┼čka bir i┼čaret├ži t├╝r├╝ne / d─▒┼č─▒na d├Ân├╝┼čt├╝r├╝lebilir (C11 6.3.2.3 ve 6.5.16.1).

  • C ++, ancak void* ba┼čka bir i┼čaret├ži t├╝r├╝ aras─▒nda ├Ârt├╝l├╝ bir d├Âk├╝m izin vermez . Yani C ++ 'da oyuncular do─čru olurdu. Fakat e─čer C ++ 'da programl─▒yorsan─▒z, kullanmal─▒s─▒n─▒z new ve malloc () de─čil. Ve C kodunu asla C ++ derleyicisi kullanarak derlememelisiniz.

    Hem C hem de C ++ '─▒ ayn─▒ kaynak kodla desteklemeniz gerekiyorsa, farkl─▒l─▒klar─▒ i┼čaretlemek i├žin derleyici anahtarlar─▒n─▒ kullan─▒n. Her iki dil standard─▒n─▒ da ayn─▒ kodla satmaya ├žal─▒┼čmay─▒n, ├ž├╝nk├╝ bunlar uyumlu de─čildir.

  • Bir C derleyicisi, ba┼čl─▒─č─▒ dahil etmeyi unuttu─čunuzdan dolay─▒ bir i┼člev bulamazsa, bu konuda bir derleyici / ba─člay─▒c─▒ hatas─▒ al─▒rs─▒n─▒z. Yani <stdlib.h> bunun bir biggie olmad─▒─č─▒n─▒ eklemeyi unutursan─▒z , program─▒n─▒z─▒ olu┼čturamazs─▒n─▒z.

  • Standartlar─▒n 25 ya┼č─▒ndan daha eski bir versiyonunu takip eden eski derleyicilerde, eklemeyi unutmak <stdlib.h> tehlikeli davran─▒┼člara neden olur. ├ç├╝nk├╝ bu eski standartta, g├Âr├╝n├╝r bir prototip i├žermeyen i┼člevler, geri d├Ân├╝┼č tipini dolayl─▒ olarak d├Ân├╝┼čt├╝rm├╝┼čt├╝r int . Sonucu a├ž─▒k├ža malloc'tan yay─▒nlamak bu hatay─▒ gizler.

    Ancak bu ger├žekten bir sorun de─čil. 25 ya┼č─▒nda bir bilgisayar kullanm─▒yorsunuz, neden 25 ya┼č─▒nda bir derleyici kullan─▒yorsunuz?


93







C'de void* , herhangi bir (veri) i┼čaretleyiciden ├Ârt├╝k bir d├Ân├╝┼č├╝m elde edersiniz .


86







D├Ând├╝r├╝len de─čeri malloc() vermek art─▒k gerekli de─čil, ancak kimsenin i┼čaret etmedi─či bir nokta eklemek istiyorum:

├ľnce eski g├╝nlerde oldu─čunu, ANSI C sa─člar void * i┼čaret├žiler jenerik t├╝r├╝ olarak, char * bu t├╝r bir kullan─▒m i├žin t├╝r├╝d├╝r. Bu durumda, oyuncu derleyici uyar─▒lar─▒n─▒ durdurabilir.

Referans: C SSS


67







Sonu├žlar─▒n─▒n yay─▒nlanmas─▒ zorunlu de─čildir malloc , ├ž├╝nk├╝ geri d├Âner void* ve a void* herhangi bir veri tipine i┼čaret edilebilir.


50







Sadece deneyimimi ekledim, bilgisayar m├╝hendisli─či okudum, C de yazarken g├Ârd├╝─č├╝m iki ya da ├╝├ž profes├Âr├╝n her zaman malloc kulland─▒─č─▒n─▒, ancak sordu─čumun (├žok b├╝y├╝k ├Âzge├žmi┼č ve C anlay─▒┼č─▒yla), bunun kesinlikle gereksiz oldu─čunu s├Âyledi. Sadece tamamen spesifikti ve ├Â─črencileri tamamen spesifik olma zihniyetine soktum. Temelde d├Âk├╝m, ├žal─▒┼čma ┼čeklindeki hi├žbir ┼čeyi de─či┼čtirmez, tam olarak ne s├Âylerse yapar, haf─▒zay─▒ tahsis eder ve yay─▒n etkilemez, ayn─▒ haf─▒zay─▒ elde edersiniz ve yanl─▒┼čl─▒kla ba┼čka bir ┼čeye atsan─▒z bile (ve bir ┼čekilde derleyiciden ka├žar) error) C ayn─▒ ┼čekilde eri┼čecektir.

D├╝zenleme: D├Âk├╝m belirli bir noktaya sahiptir. Dizi g├Âsterimini kulland─▒─č─▒n─▒zda, olu┼čturulan kodun bir sonraki eleman─▒n ba┼č─▒na ula┼čmak i├žin ka├ž haf─▒za alan─▒na ilerlemesi gerekti─čini bilmesi gerekir, bu d├Âk├╝m yoluyla elde edilir. Bu ┼čekilde, bir ├žift i├žin, bir int i├žin 4, vb. Bu nedenle, e─čer i┼čaret├ži g├Âsterimi kullan─▒rsan─▒z, dizi g├Âstermede gerekli olur.


49







Bu nedir GNU C K├╝t├╝phanesi Ba┼čvuru k─▒lavuzu diyor ki:

malloc ISO C, gerekti─činde t├╝r├╝ otomatik void * olarak ba┼čka bir i┼čaret├ži t├╝r├╝ne d├Ân├╝┼čt├╝rd├╝─č├╝ i├žin, herhangi bir i┼čaret├ži de─či┼čkeninin sonucunu d├Âk├╝m kullanmadan saklayabilirsiniz . Ancak, atama operat├Ârleri d─▒┼č─▒ndaki ba─člamlarda veya kodunuzun geleneksel C'de ├žal─▒┼čt─▒r─▒lmas─▒n─▒ isteyebilirsiniz.

Ve asl─▒nda ISO C11 standard─▒ (p347) ┼č├Âyle diyor:

E─čer tahsis ba┼čar─▒l─▒ olursa, ibre temel hizalama gereksinimi olan herhangi bir nesne tipine bir g├Âstericiye atanabilmesi ve daha sonra tahsis edilen alandaki b├Âyle bir nesneye veya bu t├╝r nesnelerin bir dizisine eri┼čmek i├žin kullan─▒lana kadar uygun bir ┼čekilde dizilir. Alan a├ž─▒k├ža kald─▒r─▒ld─▒)


31







Bir bo┼č i┼čaret├ži, genel bir i┼čaret├židir ve C, bir bo┼č i┼čaret├ži tipinden di─čer tiplere ├Ârt├╝k olarak d├Ân├╝┼čt├╝r├╝lmesini destekler, bu nedenle onu a├ž─▒k├ža tiplendirmeye gerek yoktur.

Bununla birlikte, ayn─▒ kodun ├Ârt├╝k d├Ân├╝┼čt├╝rmeyi desteklemeyen bir C ++ platformunda m├╝kemmel bir ┼čekilde uyumlu ├žal─▒┼čmas─▒n─▒ istiyorsan─▒z, yaz─▒m tahminini yapman─▒z gerekir, bu nedenle bunlar─▒n t├╝m├╝ kullan─▒labilirli─če ba─čl─▒d─▒r.


30







D├Ând├╝r├╝len t├╝r, ge├žersiz k─▒l─▒nabilmesi i├žin istenen veri i┼čaret├žisine d├Ân├╝┼čt├╝r├╝lebilen bo┼čluktur *.


29







C dilinde, herhangi bir i┼čaret├žiye ge├žersiz bir i┼čaret├ži atanabilir, bu y├╝zden bir cast t├╝r├╝ kullanmaman─▒z gerekir. E─čer "type safe" tahsisi istiyorsan─▒z, C projelerimde her zaman kulland─▒─č─▒m a┼ča─č─▒daki makro fonksiyonlar─▒n─▒ ├Ânerebilirim:

 #include <stdlib.h>
#define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
#define NEW(ptr) NEW_ARRAY((ptr), 1)
 

Bunlar─▒ yerinde kullanarak basit├že s├Âyleyebilirsiniz

 NEW_ARRAY(sieve, length);
 

Dinamik olmayan diziler i├žin ├╝├ž├╝nc├╝ sahip olmas─▒ gereken i┼člev makrosu

 #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
 

dizi d├Âng├╝ler daha g├╝venli ve daha rahat hale getirir:

 int i, a[100];

for (i = 0; i < LEN(a); i++) {
   ...
}
 

27







Programlama diline ve derleyiciye ba─čl─▒d─▒r. malloc C kullan─▒yorsan─▒z , cast yaz─▒n, ├ž├╝nk├╝ otomatik olarak cast yazacakt─▒r, ancak C ++ kullan─▒yorsan─▒z, cast yaz─▒n, ├ž├╝nk├╝ malloc bir void* t├╝r d├Ând├╝r├╝r .


26







GCC ve ClangÔÇÖa al─▒┼čk─▒n insanlar ┼č─▒mar─▒k. Oradaki o kadar iyi de─čil.

Y─▒llar boyunca kullanmak zorunda oldu─čum ┼ča┼č─▒rt─▒c─▒ ya┼čtaki derleyiciler taraf─▒ndan olduk├ža korktum. Genellikle ┼čirketler ve y├Âneticiler de─či┼čen derleyicilere ultra muhafazakar bir yakla┼č─▒m benimser ve sistemlerinde yeni bir derleyicinin (daha iyi standartlara uygunluk ve kod optimizasyonuna sahip) ├žal─▒┼č─▒p ├žal─▒┼čmayaca─č─▒n─▒ bile test etmez . ├çal─▒┼čan geli┼čtiriciler i├žin pratik ger├žek ┼ču ki, kodlama yaparken ├╝slerinizi koruman─▒z gerekir ve ne yaz─▒k ki, kodunuzu uygulamak i├žin hangi derleyicinin uygulanabilece─čini kontrol edemiyorsan─▒z malloclar d├Âkmek iyi bir al─▒┼čkanl─▒kt─▒r.

Bir├žok kurulu┼č kendilerine ait bir kodlama standard─▒ ge├žerli oldu─čunu ben de ├Âneririm ve o bu o tan─▒mlanm─▒┼čsa y├Ântem insanlar─▒n takip olmal─▒d─▒r. A├ž─▒k bir rehberli─čin yoklu─čunda, bir standarda uymak yerine her yerde derlenmesi muhtemeldir.

Mevcut standartlar alt─▒nda gerekli olmad─▒─č─▒ arg├╝man─▒ olduk├ža ge├žerlidir. Fakat bu arg├╝man ger├žek d├╝nyan─▒n pratiklerini g├Âz ard─▒ ediyor. Yaln─▒zca g├╝n├╝n standard─▒ taraf─▒ndan y├Ânetilen bir d├╝nyada kodlama de─čil, ÔÇťyerel y├Ânetimin ger├žeklik alan─▒ÔÇŁ olarak adland─▒rd─▒─č─▒m ┼čeylerin pratiklikleri taraf─▒ndan kodlan─▒r. Ve bu, ┼čimdiye kadar oldu─čundan daha fazla b├╝k├╝lm├╝┼č ve b├╝k├╝lm├╝┼č. :-)

YMMV.

Malloc'u savunma operasyonu olarak d├╝┼č├╝nmeye meyilliyim. G├╝zel de─čil, m├╝kemmel de─čil, ama genellikle g├╝venli. (Sonra stdlib.h dahil de─čildir verdiyseniz D├╝r├╝st├že, ettik yolu malloc d├Âk├╝m daha fazla probleme!).


16







Tipik sistemde ├žirkin deli─čin onaylanmamas─▒n─▒ g├Âstermek i├žin oyuncu kadrosuna koydum; bu, a┼ča─č─▒daki kod par├žac─▒─č─▒ gibi kodun, k├Ât├╝ d├Ân├╝┼č├╝m├╝ sa─člamak i├žin hi├žbir yay─▒n kullan─▒lmamas─▒na ra─čmen, tan─▒lama olmadan derlenmesini sa─člad─▒:

 double d;
void *p = &d;
int *q = p;
 

Ke┼čke bu olmasayd─▒ (ve C ++ 'da yok) ve ben de oyuncu oldum. Zevkimi ve programlama politikam─▒ temsil ediyor. Ben sadece bir i┼čaret├ži de─čil, etkili oy kullan─▒yorum, oy kullan─▒yorum ve aptall─▒k ┼čeytanlar─▒ ├ž─▒kar─▒yorum . Ben yapam─▒yorsan─▒z asl─▒nda aptall─▒k kovdu , o zaman en az─▒ndan beni protesto jesti ile bunu arzu ifade edelim.

Asl─▒nda, iyi bir uygulama, malloc (ve arkada┼člar─▒) geri d├Ânen i┼člevlerle sarmak unsigned char * ve temelde asla void * kodunuzda kullanmamakt─▒r . Herhangi bir nesneye genel bir i┼čaret├ži ihtiyac─▒n─▒z varsa, a char * veya kullan─▒n unsigned char * ve her iki y├Ânde de yay─▒nlara sahip olun. ─░ndulged edilebilir bir rahatlama, belki gibi i┼člevleri kullan─▒yor memset ve memcpy atmalar─▒n─▒ olmadan.

Bunu kodunuzu yazarsan─▒z d├Âk├╝m ve C ++ uyumlulu─ču konusunda, o C ve C hem ++ (bu durumda siz derler zorunda d├Ân├╝┼č de─čer da─č─▒tmak malloc d─▒┼č─▒nda bir ┼čeye atarken void * ), ├žok yararl─▒ yapabilirsiniz Kendin i├žin bir ┼čey: C ++ olarak derlerken C ++ stiline ├ževiren, ancak C olarak derlerken C d├Âk├╝m├╝n├╝ azaltan d├Âk├╝m i├žin makrolar─▒ kullanabilirsiniz:

 /* In a header somewhere */
#ifdef __cplusplus
#define strip_qual(TYPE, EXPR) (const_cast<TYPE>(EXPR))
#define convert(TYPE, EXPR) (static_cast<TYPE>(EXPR))
#define coerce(TYPE, EXPR) (reinterpret_cast<TYPE>(EXPR))
#else
#define strip_qual(TYPE, EXPR) ((TYPE) (EXPR))
#define convert(TYPE, EXPR) ((TYPE) (EXPR))
#define coerce(TYPE, EXPR) ((TYPE) (EXPR))
#endif
 

Bu makrolara ba─čl─▒ kal─▒rsan─▒z grep , kod tan─▒mlay─▒c─▒n─▒z i├žin bu tan─▒mlay─▒c─▒lar i├žin basit bir arama yap─▒lmas─▒, t├╝m yay─▒nlar─▒n─▒z─▒n nerede oldu─čunu g├Âsterir, b├Âylece herhangi birinin hatal─▒ olup olmad─▒─č─▒na bakabilirsiniz.

Ard─▒ndan ileriye do─čru, kodu d├╝zenli olarak C ++ ile derlerseniz, uygun bir d├Âk├╝m kullanmaya zorlar. ├ľrne─čin, strip_qual sadece bir const veya kald─▒rmak i├žin kullan─▒yorsan─▒z volatile , ancak program bir t├╝r d├Ân├╝┼čt├╝rmenin yap─▒laca─č─▒ ┼čekilde de─či┼čir, bir tan─▒lama al─▒rs─▒n─▒z ve istedi─činiz d├Ân├╝┼č├╝m├╝ elde etmek i├žin bir d├Âk├╝m kombinasyonu kullanmak zorunda kal─▒rs─▒n─▒z.

Bu makrolara uyman─▒za yard─▒mc─▒ olmak i├žin, GNU C ++ (C! De─čil) derleyicisinin g├╝zel bir ├Âzelli─či vard─▒r: C tarz─▒ yay─▒nlar─▒n t├╝m olu┼čumlar─▒ i├žin ├╝retilmi┼č iste─če ba─čl─▒ bir tan─▒lama.

     -Wold-style-cast (yaln─▒zca C ++ ve Objective-C ++)
         Bo┼č olmayan bir t├╝re d├Ân├╝┼čt├╝r├╝len eski stil (C stili) kullan─▒l─▒rsa uyar
         bir C ++ program─▒nda. Yeni stil yay─▒nlar─▒ (dynamic_cast,
         static_cast, reinterpret_cast ve const_cast) daha az savunmas─▒z
         istenmeyen etkileri ve aramak i├žin ├žok daha kolay.

C kodunuz C ++ olarak derlenirse, bu -Wold-style-cast se├žene─či (type) koda s├╝r├╝nebilecek t├╝m d├Âk├╝m s├Âzdiziminin olu┼čumlar─▒n─▒ bulmak i├žin kullanabilirsiniz ve yukar─▒daki tan─▒lamalara yukar─▒daki makrolar aras─▒ndan uygun bir se├ženekle de─či┼čtirerek (veya gerekirse, kombinasyon).

D├Ân├╝┼č├╝mlerin bu muamelesi, bir "Temiz C" de ├žal─▒┼čman─▒n tek ve en b├╝y├╝k ba─č─▒ms─▒z teknik gerek├žesidir: s─▒rayla teknik olarak geri d├Ân├╝┼č de─čerinin d├Âk├╝m├╝n├╝ hakl─▒ k─▒lan C ve C ++ leh├žesi malloc .


14


2016-03-30





Hay─▒r, sonucunu sen vermedin malloc() .

Genelde, ya da oradan oyuncuya at─▒lmazs─▒n void * .

Bunu yapmamak i├žin verilen tipik bir neden, #include <stdlib.h> fark edilmeden kalmamas─▒ndan kaynaklanmaktad─▒r . C99 art─▒k ├Ârt├╝k i┼člev bildirimlerini yasad─▒┼č─▒ k─▒ld─▒─č─▒ndan bu, art─▒k uzun zamand─▒r bir sorun de─čil , bu nedenle derleyiciniz en az─▒ndan C99'a uygunsa, bir tan─▒lama mesaj─▒ alacaks─▒n─▒z.

Ancak gereksiz i┼čaret├ži atmalar─▒n─▒ kullanmamak i├žin ├žok daha g├╝├žl├╝ bir neden var :

C'de, bir i┼čaret├ži al├ž─▒ neredeyse her zaman bir hatad─▒r . Bunun sebebi ┼ču kurald─▒r ( C11'in en son tasla─č─▒ olan N1570ÔÇÖde ┬ž6.5 p7 ):

Bir nesnenin saklanan de─čerine, yaln─▒zca a┼ča─č─▒daki t├╝rlerden birine sahip olan bir de─čer ifadesiyle eri┼čilebilecektir:
- nesnenin
etkin t├╝r├╝yle uyumlu bir t├╝r,
- nesnenin etkin t├╝r├╝yle uyumlu bir t├╝r├╝n nitelikli bir s├╝r├╝m├╝, - Nesnenin etkin t├╝r├╝ne kar┼č─▒l─▒k gelen
imzal─▒ veya imzas─▒z t├╝r olan bir t├╝r,
- Nesnenin etkin t├╝r├╝n├╝n nitelikli bir s├╝r├╝m├╝ne kar┼č─▒l─▒k gelen imzal─▒ veya imzas─▒z t├╝r olan bir t├╝r; ├╝yeleri aras─▒nda yukar─▒da belirtilen t├╝rlerin listesi (├Âzyinelemeyle, bir alt k├╝menin veya bir birli─čin bir ├╝yesi dahil) veya
- bir karakter t├╝r├╝.

Bu ayn─▒ zamanda tam takma kural olarak da bilinir . Bu nedenle, a┼ča─č─▒daki kod tan─▒ms─▒z davran─▒┼č :

 long x = 5;
double *p = (double *)&x;
double y = *p;
 

Ve bazen ┼ča┼č─▒rt─▒c─▒ bir ┼čekilde, a┼ča─č─▒dakiler de ┼č├Âyledir:

 struct foo { int x; };
struct bar { int x; int y; };
struct bar b = { 1, 2};
struct foo *p = (struct foo *)&b;
int z = p->x;
 

Bazen, do d├Âkme i┼čaret├žiler gerekir, ancak verilen s─▒k─▒ ├Ârt├╝┼čme kural─▒ , onunla ├žok dikkatli olmak zorunda. Dolay─▒s─▒yla, kodunuzda bir i┼čaret├ži olu┼čumu , ge├žerlili─čini iki kez kontrol etmeniz gereken bir yerdir . Bu nedenle, hi├žbir zaman gereksiz bir i┼čaret├ži almazs─▒n─▒z.

tl; Dr.

├ľzetle: C'de, bir i┼čaret├ži cast─▒n─▒n herhangi bir ┼čekilde olu┼čmas─▒, ├Âzel dikkat gerektiren kod i├žin k─▒rm─▒z─▒ bayrak kald─▒rmas─▒ gerekti─činden, hi├žbir zaman gereksiz i┼čaret├ži atmalar─▒n─▒ yazmamal─▒s─▒n─▒z.


Yan notlar:

  • Asl─▒nda bir al├ž─▒ya ihtiya├ž duydu─čunuz durumlar vard─▒r void * , ├Ârne─čin bir i┼čaret├ži yazd─▒rmak istiyorsan─▒z:

     int x = 5;
    printf("%p\n", (void *)&x);
     

    Al├ž─▒ burada gereklidir, ├ž├╝nk├╝ printf() de─či┼čken bir i┼člevdir, bu nedenle ├Ârt├╝k d├Ân├╝┼č├╝mler ├žal─▒┼čmaz.

  • C ++ 'da durum farkl─▒d─▒r. ─░┼čaret├ži t├╝rlerini yay─▒nlamak, t├╝retilmi┼č s─▒n─▒flar─▒n nesnelerle u─čra┼č─▒rken biraz yayg─▒nd─▒r (ve do─črudur). Bu nedenle, C ++, ve d├Ân├╝┼čt├╝rme mant─▒kl─▒ void * oldu─čunu de─čil ├Ârt├╝k. C ++ '─▒n farkl─▒ d├Âk├╝m lezzetleri var.


14


2017-08-16





M├╝mk├╝n oldu─čunda C de programlama yaparken yap─▒lacak en iyi ┼čey:

  1. T├╝m uyar─▒lar a├ž─▒kken program─▒n─▒z─▒n bir C derleyicisi arac─▒l─▒─č─▒yla derlenmesini sa─člay─▒n -Wall ve t├╝m hatalar─▒ ve uyar─▒lar─▒ d├╝zeltin
  2. Olarak bildirilen de─či┼čken olmad─▒─č─▒ndan emin olun. auto
  3. Sonra -Wall ve ile bir C ++ derleyici kullanarak derleyin -std=c++11 . T├╝m hatalar─▒ ve uyar─▒lar─▒ d├╝zeltin.
  4. ┼×imdi C derleyicisini kullanarak tekrar derleyin. Program─▒n─▒z ┼čimdi herhangi bir uyar─▒ olmadan derlenmeli ve daha az hata i├žermelidir.

Bu prosed├╝r, C ++ kat─▒ tip kontrol├╝nden faydalanman─▒za izin verir, b├Âylelikle b├Âcek say─▒s─▒n─▒ azalt─▒r. ├ľzellikle, bu prosed├╝r sizi dahil etmeye zorlar stdlib.h ya da

malloc bu kapsamda ilan edilmedi

ve ayr─▒ca sonucu ├ž─▒karmaya zorlar malloc ya da al─▒rs─▒n

Ge├žersiz d├Ân├╝┼č├╝m void* i├žin T*

ya da hedef t├╝r├╝n ne olursa olsun.

C ++ 'da bulabildi─čim C ++' a yazman─▒n faydalar─▒

  1. C iyi belirlenmi┼č bir ABI'ye sahip
  2. C ++ daha fazla kod ├╝retebilir [istisnalar, RTTI, ┼čablonlar, ├žal─▒┼čma zaman─▒ polimorfizmi]

Statik polimorfik ├Âzellik ile birlikte C'ye ortak olan altk├╝meyi kullan─▒rken, ikinci durumun ideal durumda kaybolmas─▒ gerekti─čine dikkat edin .

C ++ kurallar─▒n─▒ zor buluyorsa, C ++ 11 ├Âzelli─čini inferred t├╝r├╝yle kullanabiliriz.

 auto memblock=static_cast<T*>(malloc(n*sizeof(T))); //Mult may overflow...
 

13







Oyuncu se├žimi yapmay─▒ tercih ediyorum, ancak manuel olarak de─čil. Benim favori kullan─▒yor g_new ve g_new0 glib gelen makro. Glib kullan─▒lmazsa, benzer makrolar─▒ eklerdim. Bu makrolar, t├╝r g├╝venli─činden ├Âd├╝n vermeden kod ├žo─čaltmas─▒n─▒ azalt─▒r. T├╝r├╝ yanl─▒┼č al─▒rsan─▒z, bo┼č i┼čaret├žiler aras─▒nda ├Ârt├╝k bir d├Âk├╝m elde edersiniz, bu bir uyar─▒ya neden olur (hata C ++ 'da). Tan─▒mlayan ba┼čl─▒─č─▒ eklemeyi unutursan─▒z g_new ve g_new0 bir hata al─▒rs─▒n─▒z. g_new ve g_new0 her ikisi de ayn─▒ arg├╝manlar─▒ malloc al─▒r , aksine aksine daha az arg├╝man al─▒r calloc . 0 S─▒f─▒rlanm─▒┼č belle─či almak i├žin sadece ekleyin . Kod, de─či┼čiklik yapmadan bir C ++ derleyicisi ile derlenebilir.


13







D├Âk├╝m yaln─▒zca C ++ i├žin de─čil C'dir. Bir C ++ derleyicisi kullan─▒yorsan─▒z, onu C derleyicisine g├Âre de─či┼čtirin.


11


2015-09-10





Void g├Âstergesinin arkas─▒ndaki konsept, malloc'un void de─čerini d├Ând├╝rmesinin nedeni olarak herhangi bir veri t├╝r├╝ne at─▒labilmesidir. Ayr─▒ca otomatik tip belirlemenin fark─▒nda olmal─▒s─▒n─▒z. Bu y├╝zden, yapman─▒z gerekse de i┼čaret├žiyi kullanmak zorunlu de─čildir. Kodu temiz tutmaya yard─▒mc─▒ olur ve hata ay─▒klamaya yard─▒mc─▒ olur


10







Bir bo┼č i┼čaret├ži, genel bir i┼čaret├židir ve C, bir bo┼č i┼čaret├ži tipinden di─čer tiplere ├Ârt├╝k olarak d├Ân├╝┼čt├╝r├╝lmesini destekler, bu nedenle onu a├ž─▒k├ža tiplendirmeye gerek yoktur.

Bununla birlikte, ayn─▒ kodun ├Ârt├╝k d├Ân├╝┼čt├╝rmeyi desteklemeyen bir C ++ platformunda m├╝kemmel bir ┼čekilde uyumlu ├žal─▒┼čmas─▒n─▒ istiyorsan─▒z, yaz─▒m tahminini yapman─▒z gerekir, bu nedenle bunlar─▒n t├╝m├╝ kullan─▒labilirli─če ba─čl─▒d─▒r.


8







  1. Di─čer belirtildi─či gibi, C i├žin de─čil, C ++ i├žin gerekli de─čildir.

  2. Al├ž─▒ dahil etmek, bir C program─▒n─▒n veya fonksiyonunun C ++ olarak derlenmesine izin verebilir.

  3. C 'de gereksizdir, ├ž├╝nk├╝ bo┼čluk * otomatik olarak ve g├╝venli bir ┼čekilde di─čer i┼čaret├ži tiplerine y├╝kseltilir.

  4. Ama e─čer o zaman kulland─▒ysan─▒z, stdlib.h eklemeyi unutursan─▒z bir hatay─▒ gizleyebilirsiniz . Bu, ├ž├Âkmelere neden olabilir (veya daha da k├Ât├╝s├╝, kodun tamamen farkl─▒ bir b├Âl├╝m├╝nde daha sonraya kadar ├ž├Âkmeye neden olmaz).

    ├ç├╝nk├╝ stdlib.h malloc i├žin prototip i├žerir. Malloc i├žin bir prototip yoklu─čunda, standart, C derleyicisinin malloc'un int d├Ând├╝rd├╝─č├╝n├╝ varsaymas─▒n─▒ gerektirir. Oyuncular yoksa, bu tamsay─▒ i┼čaret├žiye atand─▒─č─▒nda bir uyar─▒ verilir; ancak, oyuncularla birlikte, bu uyar─▒ ├╝retilmez ve bir hatay─▒ gizler.


8







Malloc'un d├Âk├╝lmesi C'de gereksizdir ancak C ++ 'da zorunludur.

├ç├╝nk├╝ C'de d├Âk├╝m yapmak gereksizdir:

  • void * C durumunda otomatik olarak ve g├╝venli bir ┼čekilde di─čer i┼čaret├ži tiplerine y├╝kseltilir.
  • Eklemeyi unuttuysan─▒z bir hatay─▒ gizleyebilir <stdlib.h> . Bu, ├ž├Âkmelere neden olabilir.
  • ─░┼čaret├žiler ve tamsay─▒lar farkl─▒ boyuttalarsa, o zaman oyuncular─▒ se├žerek bir uyar─▒y─▒ gizliyorsunuz ve iade etti─činiz adresin bitlerini kaybedebilirsiniz.
  • ─░┼čaret├žinin t├╝r├╝ bildirgesinde de─či┼čtirilirse malloc , ├ža─čr─▒lan ve kullan─▒lan t├╝m sat─▒rlar─▒ de─či┼čtirmeniz gerekebilir .

Di─čer yandan, d├Âk├╝m, program─▒n─▒z─▒n ta┼č─▒nabilirli─čini art─▒rabilir. yani, bir C program─▒n─▒n veya fonksiyonunun C ++ olarak derlenmesine izin verir.


5



─░lgili yay─▒nlar


Git Bash'in 'git diff' sonu├žlar─▒ndan pencerelerde nas─▒l ├ž─▒kar─▒m? [├žift]

RxJs 5'deki Angular Http a─č aramas─▒n─▒n sonucunu payla┼čman─▒n do─čru yolu nedir?

SQLite: Bir sorgunun sonucunu CSV dosyas─▒ olarak nas─▒l kaydederim?

FindViewById sonucunu ├ž─▒karman─▒za gerek yok mu?

C# Float ifadesi: sonucu float int'ye d├Ân├╝┼čt├╝r├╝rken garip davran─▒┼č

Windows'ta bir de─či┼čkendeki bir komutun sonucunu nas─▒l alabilirim?

Windows toplu i┼č dosyas─▒nda bir komutun sonucuyla bir de─či┼čkenin de─čerini ayarlay─▒n

Spesifik olarak, malloc sonucunu atmak i├žin tehlikeli olan ne?

Diff sonu├žlar─▒nda nas─▒l gezinirim?

Bir ├Ânceki ifadenin sonucu de─či┼čkene nas─▒l atan─▒r?

Etiketle ilgili di─čer sorular [c]


Dize ve C# 'daki string aras─▒ndaki fark nedir?

ÔÇťPxÔÇŁ, ÔÇťdipÔÇŁ, ÔÇťdpÔÇŁ ve ÔÇťspÔÇŁ aras─▒ndaki fark nedir?

Git'teki birden fazla komisyonun yazar─▒ ve sahibi ad─▒ ve e-postas─▒ nas─▒l de─či┼čtirilir?

Stdout ve stderr'i Bash ile bir dosyaya nas─▒l y├Ânlendirebilir ve ekleyebilirim?

Utf8_general_ci ve utf8_unicode_ci aras─▒ndaki fark nedir

Looper.prepare () adl─▒ bir i┼č par├žac─▒─č─▒ i├žinde i┼čleyici olu┼čturulam─▒yor

C++ programc─▒lar─▒ neden 'yeni' kullan─▒m─▒n─▒ en aza indirmeli?

JavaScript'te string e┼čitli─čini kontrol etmenin do─čru yolu nedir?

PHP'de bir dosya uzant─▒s─▒n─▒ nas─▒l alabilirim?

R'deki ÔÇť=ÔÇŁ ve ÔÇť<-ÔÇŁ atama i┼čle├žleri aras─▒ndaki farklar nelerdir?