C ++ karakter dizisi [] bellek sızıntısı [yineleme]

Aug 18 2020

char arr [] 'ı yarattım ve ona dize hazır bilgisi

char arr[] = "some string";                  // arr occupies 12 chars in memory
std::cout << std::strlen(arr)  << std::endl; // lenght is 11 chars + 1 null-terminator
                                             //arr[11] is '\0'

sonraki 6 elemente boş sonlandırıcı koyuyorum

arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars  + 1 null-terminator
  1. Hafıza sızıntısı mı?
  2. Derleyici, ilk "\ 0" dan sonra belleği boşaltması gerektiğini nasıl bilecek? (dizi değişkenini ne zaman silecek)
  3. Bu arr değişkeninin uzunluğunu değiştirmek ve derleyiciye değişkeni silerken ne kadar boş olması gerektiğini bildirmek mümkün mü?

Yanıtlar

5 user253751 Aug 18 2020 at 13:03
  1. Hafıza sızıntısı mı?

Hayır.

  1. Derleyici, ilk "\ 0" dan sonra belleği boşaltması gerektiğini nasıl bilecek? (dizi değişkenini ne zaman silecek)

Değişken 12 karakterdir. Yazmakla aynı şey:

char arr[12] = "some string";

Bu yüzden her zaman 12 karakter serbest kalacak. Değişken olan 12 karakter dizisi; 6. karakterin '\ 0' olması tamamen alakasızdır.

Bu arada, 6. karakteri "\ 0" olarak ayarladıktan sonra, 12 karakterin tamamını kullanmaya devam edebilirsiniz, çünkü bu hala 12 karakterlik bir dizi. "\ 0" dan sonra olanlar bile. Ama içinde 13 karakter saklayamazsınız.

  1. Bu arr değişkeninin uzunluğunu değiştirmek ve derleyiciye değişkeni silerken ne kadar boş olması gerektiğini bildirmek mümkün mü?

Hayır. Herhangi bir değişkenin boyutunu değiştirmek mümkün değildir.

6 cigien Aug 18 2020 at 13:03

Bu kodda:

char arr[] = "some string";

değişken arr, sabit boyutlu statik bir dizidir. Burada dinamik bellek tahsisi yoktur ve bu nedenle bellek sızıntıları konusunda endişelenmenize gerek yoktur. Derleyici, ne yazdığınızdan bağımsız olarak hafızayla ilgilenecektir arr.

2 JoopEggen Aug 18 2020 at 13:07

Tamamlamak için.

Ayrılan bellekte de aşağıdaki gibi bellek sızıntısı yoktur:

char* arr = (char*) malloc(12);
strcpy(arr, "some string");
arr[6] = '\0';
free(arr);

Bellek yönetimi, temeldeki kullanıma (nul-terminated char *) değil, tahsis edilmiş belleğe (12) gider. (C stili, C ++ aynı şekilde)

1 Slava Aug 18 2020 at 13:56

Görünüşe göre geri almışsın. C ++ 'daki dizi boyutu değiştirilemez, nokta. Bu gerçek ve diziyi bir işaretçi olarak geçirirseniz , C stili dizgiler için o dizi sözleşmesinin gerçek boyutuna ilişkin bilgileri kaybettiğiniz için - 0 bayt, \0null sonlandırıcı, dizenin dinamik sonu olarak değerlendirilir. Anlaşma, C tarzı dizelerle çalışan işlevlerin bunu dize sonlandırma olarak ele aldığı anlamına gelir. Bu, farklı uzunluktaki dizeler için sabit boyutlu dizi kullanmanıza ve gerçek bellek boyutu olmadan yalnızca bir işaretçiyi ondan okumak için işlevlere (örneğin ekrana yazdır) geçirmenize olanak tanır. Dikkat ederseniz, char dizisini içine veri yazan işlevlere ilettiğinizde, ona gerçek dizi boyutunun ne olduğunu söylemeniz gerekir , böylece işlev zaten varsa boş sonlandırıcıyı yoksayacağından, işlev sınırlar dışındaki belleğe erişemez.

İşte bu, bu anlaşma dizilerin yönettiği farklı katmanda gerçekleşir. Bu nedenle, bu diziye ne veri koyarsanız koyun, dil açısından boyutunu etkilemez, C ++ derleyicisi için sabit boyutlu dizi oluşturdunuz, içine bir miktar veri koyarsınız ve ömrü sona geldiğinde derleyici onu tam sabit boyutlu dizi olarak yok eder. Oraya sıfır bayt koyup koymamanız umurunda değil.

VladfromMoscow Aug 18 2020 at 13:16

Operatörü kullanan programcı tarafından bir bellek tahsis edildiğinde newve operatör deleteveya kullanılarak silinmediğinde bir bellek sızıntısı oluşur delete [].

Bu beyannamede

char arr[] = "some string"; 

Otomatik depolama süresine veya statik depolama süresine sahip olan, karakter dizisi dizisine ayrılmış olan derleyici (veya sistem) bellektir. Bu nedenle, derleyici (veya sistem) ayrılan belleği boşaltmaktan sorumludur. Ayrılan belleğin adresi derleyici (veya sistem) tarafından bilinir.

Bu ifadeyi kullanarak

arr[5] = '\0';

diziyi yeniden tahsis etmediniz. İçeriğini daha kesin olarak yalnızca baytını değiştirdiniz.

Derleyici, ilk "\ 0" dan sonra belleği boşaltması gerektiğini nasıl bilecek? (dizi değişkenini ne zaman silecek)

Çünkü derleyici (veya sistem), dizi türünün nesnesinin nasıl bildirildiğini bilir.

Nesne için 12 bayt ayrıldı.

char arr[] = "some string"; 

Bu arr değişkeninin uzunluğunu değiştirmek ve derleyiciye değişkeni silerken ne kadar boş olması gerektiğini bildirmek mümkün mü?

Sanırım nesnenin boyutu demek istiyorsun. Hayır, nesnenin boyutunu değiştiremezsiniz çünkü nesneye bellek ayıran siz değildiniz.

newÖrneğin, ayırmak için operatörü kullandıysanız, nesneyi yeniden tahsis edebilirsiniz.

char *arr = new char[12];

std::strcpy( arr, "some string" );

//...

char *tmp = new char[20];

strcpy( tmp, "another " );
strcat( tmp, arr );

delete [] arr;
arr = tmp;