C ++ char array [] kebocoran memori [duplikat]

Aug 18 2020

saya membuat char arr [] dan menetapkannya string literal

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'

selanjutnya saya memasukkan null-terminator menjadi 6 elemen

arr[5] = '\0';
std::cout << std::strlen(arr) << std::endl; // lenght is 5 chars  + 1 null-terminator
  1. Apakah ini kebocoran memori?
  2. Bagaimana kompilator mengetahui bahwa ia harus membebaskan memori setelah '\ 0' pertama? (kapan akan menghapus variabel arr)
  3. Apakah mungkin untuk mengubah panjang variabel arr ini dan memberitahu compiler berapa banyak yang harus dikosongkan saat menghapus variabel?

Jawaban

5 user253751 Aug 18 2020 at 13:03
  1. Apakah ini kebocoran memori?

Tidak.

  1. Bagaimana kompilator mengetahui bahwa ia harus membebaskan memori setelah '\ 0' pertama? (kapan akan menghapus variabel arr)

Variabelnya adalah 12 karakter. Ini sama dengan menulis:

char arr[12] = "some string";

Jadi itu akan selalu membebaskan 12 karakter. Variabelnya adalah array 12 karakter; fakta bahwa karakter ke-6 kebetulan adalah '\ 0' sama sekali tidak relevan.

Ngomong-ngomong, setelah Anda menyetel karakter ke-6 menjadi '\ 0', Anda masih diizinkan untuk menggunakan semua 12 karakter, karena itu masih berupa larik 12 karakter. Bahkan yang setelah '\ 0'. Tetapi Anda tidak dapat menyimpan 13 karakter di dalamnya.

  1. Apakah mungkin untuk mengubah panjang variabel arr ini dan memberitahu compiler berapa banyak yang harus dikosongkan saat menghapus variabel?

Tidak. Tidak mungkin mengubah ukuran variabel apa pun.

6 cigien Aug 18 2020 at 13:03

Dalam kode ini:

char arr[] = "some string";

variabelnya arradalah array statis dengan ukuran tetap. Tidak ada alokasi memori dinamis di sini, jadi tidak perlu khawatir tentang kebocoran memori. Kompilator akan mengurus memori, apa pun yang Anda tulis arr.

2 JoopEggen Aug 18 2020 at 13:07

Untuk kelengkapan.

Juga tidak ada kebocoran memori di memori yang dialokasikan, seperti di:

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

Manajemen memori berjalan dengan memori yang dialokasikan (12), bukan dengan penggunaan yang mendasarinya (karakter nul-terminated *). (Gaya C, C ++ juga)

1 Slava Aug 18 2020 at 13:56

Sepertinya Anda mendapatkannya mundur. Ukuran larik di C ++ tidak dapat diubah, titik. Karena fakta itu dan karena fakta bahwa jika Anda melewatkan array sebagai pointer Anda kehilangan informasi ukuran sebenarnya dari perjanjian array itu dibuat untuk string gaya C - 0 byte alias \0terminator nol yang diperlakukan sebagai akhir dinamis dari string. Perjanjian berarti bahwa fungsi yang bekerja dengan string gaya C memperlakukannya sebagai penghentian string. Itu memungkinkan Anda menggunakan larik ukuran tetap untuk string dengan panjang berbeda dan hanya meneruskan satu penunjuk tanpa ukuran memori aktual ke fungsi untuk membacanya (misalnya cetak ke layar). Perhatikan, ketika Anda meneruskan char array ke fungsi yang menulis data ke dalamnya, Anda sering perlu memberi tahu apa itu ukuran array sebenarnya , sehingga fungsi itu tidak akan mengakses memori di luar batas karena fungsi tersebut akan mengabaikan terminator null jika sudah ada.

Itu saja, perjanjian ini terjadi pada lapisan berbeda yang dikelola array. Jadi, data apa pun yang Anda masukkan ke dalam array itu tidak akan memengaruhi ukurannya dari sudut pandang bahasa, untuk kompiler C ++ Anda membuat array ukuran tetap, Anda memasukkan beberapa data ke dalamnya dan ketika masa pakainya tiba, kompiler menghancurkannya sebagai array ukuran tetap secara keseluruhan. Tidak peduli jika Anda meletakkan nol byte di sana atau tidak.

VladfromMoscow Aug 18 2020 at 13:16

Kebocoran memori terjadi ketika memori dialokasikan oleh pemrogram menggunakan operator newdan tidak dihapus menggunakan operator deleteatau delete [].

Dalam deklarasi ini

char arr[] = "some string"; 

Ini adalah kompilator (atau sistem) mengalokasikan memori untuk array array karakter yang memiliki baik durasi penyimpanan otomatis atau durasi penyimpanan statis. Jadi kompilator (atau sistem) bertanggung jawab untuk membebaskan memori yang dialokasikan. Alamat dari memori yang dialokasikan diketahui oleh kompilator (atau sistem).

Menggunakan pernyataan ini

arr[5] = '\0';

Anda tidak mengalokasikan kembali array tersebut. Anda baru saja mengubah isinya lebih tepatnya hanya satu byte-nya.

Bagaimana kompilator mengetahui bahwa ia harus membebaskan memori setelah '\ 0' pertama? (kapan akan menghapus variabel arr)

Karena kompilator (atau sistem) mengetahui bagaimana objek tipe array dideklarasikan.

Untuk objek dialokasikan 12 byte.

char arr[] = "some string"; 

Apakah mungkin untuk mengubah panjang variabel arr ini dan memberitahu compiler berapa banyak yang harus dikosongkan saat menghapus variabel?

Saya pikir yang Anda maksud adalah ukuran benda. Tidak, Anda tidak dapat mengubah ukuran objek karena bukan Anda yang mengalokasikan memori untuk objek tersebut.

Anda dapat mengalokasikan kembali objek tersebut jika Anda menggunakan operator newuntuk mengalokasikannya sebagai contoh

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;