Cakupan variabel C [duplikat]

Kemungkinan Duplikat:
Apakah mengembalikan alamat literal string dari suatu fungsi aman dan portabel?
seumur hidup string literal di C

Halo saya agak bingung

char *func()
 {

    return "Hello";
 }

Di sini "Halo" adalah urutan/array karakter. Ini adalah variabel lokal dan harus hilang segera setelah fungsinya kembali. Lalu kenapa kita bisa mendapatkan nilai yang benar?


person Community    schedule 27.08.2012    source sumber
comment
Bukankah itu UB? bukankah Anda mendapat peringatan dari kompiler Anda?   -  person Neel Basu    schedule 27.08.2012
comment
Tidak, dalam hal ini tidak, karena string disimpan dalam alamat memori konstan.   -  person Constantinius    schedule 27.08.2012
comment
Tapi dia kembali char* bukan const char* bukan UB?   -  person Neel Basu    schedule 27.08.2012
comment
@NeelBasu Apakah literal String tidak dialokasikan di tumpukan?   -  person    schedule 27.08.2012
comment
@Constantinius Apakah literal String tidak dialokasikan di tumpukan?   -  person    schedule 27.08.2012


Jawaban (4)


"Hello" adalah string literal dan akan ada selama masa program. Mengutip bagian yang relevan dari standar C99:

  • 6.4.5 String literal

...Urutan karakter multibyte kemudian digunakan untuk menginisialisasi larik dengan durasi penyimpanan statis dan panjangnya cukup untuk memuat urutan...

  • 6.2.4 Durasi penyimpanan benda

Objek yang pengidentifikasinya dideklarasikan dengan tautan eksternal atau internal, atau dengan penentu kelas penyimpanan statis memiliki durasi penyimpanan statis. Masa pakainya adalah keseluruhan eksekusi program dan nilai tersimpannya diinisialisasi hanya sekali, sebelum program dimulai.

Nilai kembalian fungsi harus const char* karena upaya untuk mengubah string literal adalah perilaku yang tidak terdefinisi.

person hmjd    schedule 27.08.2012
comment
Apakah literal Strin tidak disimpan di tumpukan? Apakah mereka dialokasikan dari heap? - person ; 27.08.2012
comment
@GreatCoder Mereka dialokasikan dalam memori read-only, kemungkinan disebut .rodata atau linker-gibberish serupa. - person Lundin; 27.08.2012
comment
@GreatCoder, mereka tidak disimpan di stack atau heap. Mereka akan dikompilasi langsung dalam biner yang dihasilkan. Saya berpikir wilayah biner tempat literal string dikompilasi diberi nama area data. - person hmjd; 27.08.2012
comment
@hmjd Biasanya linker akan memiliki satu segmen .data dan satu segmen .rodata yang mana segmen pertama adalah untuk semua variabel durasi penyimpanan statis (yang tidak diinisialisasi ke nol, yaitu dalam .bss) dan segmen terakhir adalah untuk variabel read-only, yaitu konstanta dan string literal. - person Lundin; 27.08.2012
comment
@Lundin, terima kasih. Saya mengetahui dua bagian tersebut (diinisialisasi dan tidak) tetapi tidak tahu namanya. - person hmjd; 27.08.2012
comment
Salah satu cara untuk memikirkannya adalah dengan menganggap string literal seperti "a" setara dengan adanya deklarasi static const char string_a[] = {'a', '\0'};, dan semua penggunaan "a" diganti dengan string_a, secara global, dengan kemungkinan tabrakan juga akan diciutkan. - person unwind; 27.08.2012

Itu konstan dan memiliki alamat konstan di memori.

person nshy    schedule 27.08.2012
comment
Bagaimana ? dia tidak pernah menentukan const - person Neel Basu; 27.08.2012
comment
@NeelBasu Ok, lebih tepatnya string literal. - person nshy; 27.08.2012
comment
itu selalu terjadi untuk string literal. - person Hicham; 27.08.2012

Fungsi tersebut menghancurkan nilai hanya setelah mengembalikan kontrol.

Jadi, pada saat pernyataan return ditemukan, "Halo" ditempatkan untuk mengembalikan nilai dan kemudian fungsi tersebut menghancurkan cakupannya;

person vivek_jonam    schedule 27.08.2012
comment
Maka itu akan crash saat runtime. pertanyaan menyebutkan Lalu kenapa kita bisa mendapatkan nilai yang benar - person Neel Basu; 27.08.2012
comment
Anda salah karena string literal bukanlah variabel lokal (otomatis) dan tidak dialokasikan pada tumpukan, melainkan sebagai memori statis hanya-baca yang konstan. - person Lundin; 27.08.2012

lihat ini: Sedang kembali alamat literal string dari suatu fungsi yang aman dan portabel?

bahkan jika string dihapus (variabel lokal atau alokasi dinamis dengan malloc() dan free()) , saat Anda mengembalikan sebuah pointer, nilainya bisa saja benar. tapi, ini adalah perilaku yang tidak dapat dijelaskan.

person Hicham    schedule 27.08.2012