Seperti segala sesuatu yang tampak lebih menakutkan pada awalnya daripada kemudian, cara terbaik untuk mengatasi rasa takut awal adalah dengan membenamkan diri Anda ke dalam ketidaknyamanan yang tidak diketahui ! Pada saat-saat seperti itulah yang paling banyak kita pelajari.
Sayangnya, ada batasannya. Saat Anda masih belajar untuk menggunakan suatu fungsi, Anda tidak seharusnya mengambil peran sebagai guru, misalnya. Saya sering membaca jawaban dari mereka yang tampaknya tidak tahu cara menggunakan realloc
(yaitu jawaban yang saat ini diterima! ) Memberi tahu orang lain bagaimana menggunakannya secara salah, kadang-kadang dengan kedok bahwa mereka telah menghilangkan penanganan kesalahan , meskipun ini adalah perangkap umum yang perlu disebutkan. Inilah jawaban yang menjelaskan cara menggunakan realloc
dengan benar . Perhatikan bahwa jawabannya menyimpan nilai balik ke variabel yang berbeda untuk melakukan pengecekan kesalahan.
Setiap kali Anda memanggil fungsi, dan setiap kali Anda menggunakan array, Anda menggunakan pointer. Konversi ini terjadi secara implisit, yang jika sesuatu harus lebih menakutkan, karena hal-hal yang tidak kita lihat yang paling sering menyebabkan masalah. Misalnya, kebocoran memori ...
Operator array adalah operator pointer. array[x]
benar-benar jalan pintas untuk *(array + x)
, yang dapat dipecah menjadi: *
dan (array + x)
. Kemungkinan besar itulah *
yang membingungkan Anda. Kami lebih lanjut dapat menghilangkan penambahan dari masalah dengan mengasumsikan x
menjadi 0
, dengan demikian, array[0]
menjadi *array
karena menambahkan 0
tidak akan mengubah nilai ...
... dan dengan demikian kita dapat melihat bahwa *array
itu setara dengan array[0]
. Anda dapat menggunakan satu di mana Anda ingin menggunakan yang lain, dan sebaliknya. Operator array adalah operator pointer.
malloc
, realloc
dan teman tidak menemukan konsep pointer yang telah Anda gunakan selama ini; mereka hanya menggunakan ini untuk mengimplementasikan beberapa fitur lain, yang merupakan bentuk berbeda dari durasi penyimpanan, paling cocok ketika Anda menginginkan perubahan ukuran yang drastis dan dinamis .
Sangat memalukan bahwa jawaban yang saat ini diterima juga bertentangan dengan saran-saran lain yang sangat beralasan tentang StackOverflow , dan pada saat yang sama, kehilangan kesempatan untuk memperkenalkan fitur yang tidak banyak diketahui yang menyinari dengan tepat usecase ini: array fleksibel anggota! Itu sebenarnya jawaban yang cukup rusak ... :(
Ketika Anda mendefinisikan Anda struct
, mendeklarasikan array Anda di akhir struktur, tanpa batas atas. Sebagai contoh:
struct int_list {
size_t size;
int value[];
};
Ini akan memungkinkan Anda untuk menyatukan array Anda int
ke dalam alokasi yang sama dengan Anda count
, dan mengikat mereka seperti ini bisa sangat berguna !
sizeof (struct int_list)
akan bertindak seolah-olah value
memiliki ukuran 0, jadi itu akan memberi tahu Anda ukuran struktur dengan daftar kosong . Anda masih perlu menambahkan ukuran yang diteruskan ke realloc
untuk menentukan ukuran daftar Anda.
Tip berguna lainnya adalah untuk mengingat yang realloc(NULL, x)
setara dengan malloc(x)
, dan kita dapat menggunakan ini untuk menyederhanakan kode kita. Sebagai contoh:
int push_back(struct int_list **fubar, int value) {
size_t x = *fubar ? fubar[0]->size : 0
, y = x + 1;
if ((x & y) == 0) {
void *temp = realloc(*fubar, sizeof **fubar
+ (x + y) * sizeof fubar[0]->value[0]);
if (!temp) { return 1; }
*fubar = temp; // or, if you like, `fubar[0] = temp;`
}
fubar[0]->value[x] = value;
fubar[0]->size = y;
return 0;
}
struct int_list *array = NULL;
Alasan saya memilih untuk menggunakan struct int_list **
sebagai argumen pertama mungkin tidak langsung tampak jelas, tetapi jika Anda berpikir tentang argumen kedua, setiap perubahan yang dibuat value
dari dalam push_back
tidak akan terlihat oleh fungsi yang kami panggil, kan? Hal yang sama berlaku untuk argumen pertama, dan kita harus dapat memodifikasi kita array
, tidak hanya di sini tetapi mungkin juga dalam fungsi lain / s kita berikan kepada ...
array
mulai menunjuk apa-apa; ini adalah daftar kosong. Menginisialisasi itu sama dengan menambahkannya. Sebagai contoh:
struct int_list *array = NULL;
if (!push_back(&array, 42)) {
// success!
}
PS Ingatfree(array);
ketika Anda selesai dengan itu!