배열의 새로운 이식성 배치
표준 라이브러리의 배치 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!