Rumah >pembangunan bahagian belakang >C++ >Adakah Mengakses Elemen Tatasusunan 2D Menggunakan Aritmetik Penunjuk Melampaui Hadnya Menghasilkan Gelagat Tidak Ditakrifkan?

Adakah Mengakses Elemen Tatasusunan 2D Menggunakan Aritmetik Penunjuk Melampaui Hadnya Menghasilkan Gelagat Tidak Ditakrifkan?

Mary-Kate Olsen
Mary-Kate Olsenasal
2024-12-31 12:35:09516semak imbas

Does Accessing a 2D Array Element Using Pointer Arithmetic Beyond Its Bounds Result in Undefined Behavior?

Bolehkah Tatasusunan 2D Diperlakukan sebagai Tatasusunan 1D Bercantum?

Pertimbangkan coretan kod berikut:

int a[25][80];
a[0][1234] = 56;
int* p = &a[0][0];
p[1234] = 56;

Soalan: Adakah kod mengakses tatasusunan di luar tatasusunannya sempadan, mengakibatkan gelagat tidak ditentukan?

Jawapan: Ya, kedua-dua baris 2 dan 4 mempamerkan gelagat tidak ditentukan.

Dalam C , pengindeksan tatasusunan pada asasnya ialah aritmetik penunjuk. Apabila mengakses a[i][j], pengkompil secara berkesan menterjemahkannya kepada *(a[i] j). Begitu juga, p[i] merujuk kepada *(p i).

Dalam kes ini, tatasusunan a mempunyai dimensi 25 x 80. Baris pertama tatasusunan, a[0], mengandungi 80 elemen (mulai daripada a[0][0] kepada a[0][79]) dan diperuntukkan di lokasi memori bersebelahan.

Dengan mengakses a[0][1234], kod tersebut cuba mengakses elemen pada indeks 1234 dalam baris pertama, walaupun a[0] hanya mengandungi unsur dalam julat [0, 79]. Ini di luar had dan mencetuskan gelagat yang tidak ditentukan.

Logik yang sama digunakan pada baris 4. Walaupun p menunjuk ke elemen pertama a[0], tatasusunan masih berdimensi sebagai 25 x 80. Mengakses p[ 1234] pada asasnya ialah operasi aritmetik penunjuk di luar sempadan, sekali lagi membawa kepada tidak ditentukan tingkah laku.

Selain itu, seperti yang dinyatakan oleh Language Lawyer dalam ulasan, coretan kod yang serupa menggunakan constexpr akan gagal dihimpun kerana pengkompil mengesan gelagat yang tidak ditentukan sedemikian dalam ungkapan tetap:

constexpr int f(const int (&a)[2][3])
{
    auto p = &a[0][0];
    return p[3];
}

int main()
{
    constexpr int a[2][3] = { 1, 2, 3, 4, 5, 6, };
    constexpr int i = f(a);
}

Ini menyusun dengan betul kerana mengakses p[3] menggunakan constexpr mencetuskan pengkompil untuk mengesan tingkah laku yang tidak ditentukan dan membuang ralat.

Atas ialah kandungan terperinci Adakah Mengakses Elemen Tatasusunan 2D Menggunakan Aritmetik Penunjuk Melampaui Hadnya Menghasilkan Gelagat Tidak Ditakrifkan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn