Adakah Menggunakan Peletakan Baharu pada C Arrays Mudah Alih?

DDD
Lepaskan: 2024-11-18 05:38:02
asal
625 orang telah melayarinya

Is Using Placement New on C   Arrays Portable?

Penempatan Mudah Alih Baharu untuk Tatasusunan

Operator baharu penempatan perpustakaan standard membenarkan peruntukan memori pada alamat yang ditentukan. Walau bagaimanapun, penggunaannya dengan tatasusunan menimbulkan kebimbangan tentang kemudahalihan disebabkan kemungkinan percanggahan antara penuding yang dikembalikan dan alamat yang dihantar masuk.

Memahami Masalah

Apabila menggunakan peletakan baharu untuk tatasusunan, penunjuk yang dikembalikan mungkin tidak sejajar dengan alamat yang diberikan. Ini dijelaskan dalam Nota 12 daripada 5.3.4 piawaian C. Akibatnya, memperuntukkan penimbal khusus untuk tatasusunan menjadi bermasalah.

Pertimbangkan contoh berikut:

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = new(pBuffer) A[NUMELEMENTS];

    // Output may show pA as four bytes higher than pBuffer
    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    delete[] pBuffer;

    return 0;
}
Salin selepas log masuk

Contoh ini sering mengakibatkan kerosakan memori di bawah Microsoft Visual Studio. Pemeriksaan memori mendedahkan bahawa pengkompil memberi awalan peruntukan tatasusunan dengan empat bait, mungkin menyimpan kiraan elemen tatasusunan. Tingkah laku ini berbeza-beza bergantung pada pengkompil dan kelas yang digunakan.

Penyelesaian Mudah Alih

Untuk menangani isu mudah alih ini, elakkan menggunakan peletakan baharu secara langsung pada tatasusunan. Sebaliknya, pertimbangkan untuk memperuntukkan setiap elemen tatasusunan secara individu menggunakan peletakan baharu:

#include <iostream>
#include <new>

class A {
public:
    A() : data(0) {}
    ~A() {}
    int data;
};

int main() {
    const int NUMELEMENTS = 20;

    char *pBuffer = new char[NUMELEMENTS * sizeof(A)];
    A *pA = (A*)pBuffer;

    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i] = new (pA + i) A();
    }

    std::cout << "Buffer address: " << pBuffer << ", Array address: " << pA << std::endl;

    // Remember to manually destroy each element
    for (int i = 0; i < NUMELEMENTS; ++i) {
        pA[i].~A();
    }

    delete[] pBuffer;

    return 0;
}
Salin selepas log masuk

Tidak kira pendekatan yang diambil, memusnahkan setiap elemen tatasusunan secara manual sebelum memadam penimbal adalah penting untuk mengelakkan kebocoran memori.

Atas ialah kandungan terperinci Adakah Menggunakan Peletakan Baharu pada C Arrays Mudah Alih?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan