>  기사  >  백엔드 개발  >  C 배열 이식성이 뛰어난 배치 사용이 가능합니까?

C 배열 이식성이 뛰어난 배치 사용이 가능합니까?

DDD
DDD원래의
2024-11-18 05:38:02626검색

Is Using Placement New on C   Arrays Portable?

배열의 새로운 이식성 배치

표준 라이브러리의 배치 new 연산자를 사용하면 지정된 주소에 메모리를 할당할 수 있습니다. 그러나 배열과 함께 사용하면 반환된 포인터와 전달된 주소 사이의 잠재적 불일치로 인해 이식성에 대한 우려가 제기됩니다.

문제 이해

new 배치를 사용하는 경우 배열의 경우 반환된 포인터가 제공된 주소와 정렬되지 않을 수 있습니다. 이는 C 표준 5.3.4의 Note 12에 설명되어 있습니다. 결과적으로, 배열에 특별히 버퍼를 할당하는 것은 문제가 됩니다.

다음 예를 고려하십시오.

#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;
}

이 예는 Microsoft Visual Studio에서 메모리 손상을 초래하는 경우가 많습니다. 메모리를 조사해 보면 컴파일러가 배열 할당 앞에 4바이트를 추가하여 배열 요소 수를 저장할 가능성이 있음을 알 수 있습니다. 이 동작은 사용된 컴파일러와 클래스에 따라 다릅니다.

이식 가능한 솔루션

이 이식성 문제를 해결하려면 배열에 직접 배치 new를 사용하지 마십시오. 대신 새로운 배치를 사용하여 배열의 각 요소를 개별적으로 할당하는 것이 좋습니다.

#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;
}

취한 접근 방식에 관계없이 버퍼를 삭제하기 전에 각 배열 요소를 수동으로 삭제하는 것이 메모리 누수를 방지하는 데 중요합니다.

위 내용은 C 배열 이식성이 뛰어난 배치 사용이 가능합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.