문제

은 그것을 가능하여 실제로 사용하의 위치에 새로운 휴대용 코드를 사용하는 경우 그에 대한 배열?

그것은 나타납니다 포인터에서 돌아올 새로운[]는 항상 동일한 주소에 전달(5.3.4,주 12 에서 표준를 확인하는 것이 올바른지),그러나 나는 볼 수 없는 방법에 할당할 수 있는 버퍼에 대한 배열에 이동하는 경우 이러한 경우입니다.

다음 예는 문제입니다.컴파일을 Visual Studio,이 예에서는 메모리 손상:

#include <new>
#include <stdio.h>

class A
{
    public:

    A() : data(0) {}
    virtual ~A() {}
    int data;
};

int main()
{
    const int NUMELEMENTS=20;

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

    // With VC++, pA will be four bytes higher than pBuffer
    printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);

    // Debug runtime will assert here due to heap corruption
    delete[] pBuffer;

    return 0;
}

보고에서는 메모리,컴파일러를 사용하는 것은 먼저 네 개의 바이트 버퍼 저장소의 개수에 있는 항목의 수니다.이는 것을 의미하기 때문에 버퍼만 sizeof(A)*NUMELEMENTS 빅데,지난 요소를 배열에 기록으로 할당되지 않은 힙.

이렇게 질문을 찾을 수 있습니 얼마나 많은 추가적인 오버헤드를 구현하고 싶을 사용하기 위해서는 새로운 배치[]안전하게?이상적으로,필요한 기술을 휴대용 사이 서로 다른 컴파일러입니다.참고로,적어도 VC 의 경우,오버헤드를 보인다는 다른 다른 클래스입니다.예를 들어,를 제거하는 경우 가상의 소멸자를 들어,주소에서 반환된 새로운[]은 동일한 주소로 전달합니다.

도움이 되었습니까?

해결책

개인적으로 이 옵션을 사용하지 않는 배치에서 새로 편안하고 대신 사용하여 배치에서 새로이 각 항목 배열에 있습니다.예를 들어:

int main(int argc, char* argv[])
{
  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();
  }

  printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);

  // dont forget to destroy!
  for(int i = 0; i < NUMELEMENTS; ++i)
  {
    pA[i].~A();
  }    

  delete[] pBuffer;

  return 0;
}

는 방법에 관계 없이,당신이 사용하는지 확인할 수동으로 파괴하는 사람들의 각각의 항목 배열을 삭제하기 전에 pBuffer,으로 끝날 수 있었으로 누출;)

참고:나지 않은 컴파일이지만,그것을 생각해야 합 작업(나는 컴퓨터에서는 C++컴파일러가 설치되).그것은 여전히 나타내는점:)희망에 도움이 됩니다.


편집:

의 이유로 그것을 요구하는 추적 요소의 개수입니다 그래서 그것을 반복할 수 있을 때 당신이 전화에서 삭제를 배열하고 있는지 확인의 소멸자에서 근무하고 있으며 각각의 개체입니다.지 않는 경우 알고 얼마나 많은지 않는 것이 이것을 할 수 있다.

다른 팁

@Derek

5.3.4,12 절에 대해 이야기 할당 배열 오버헤드지 않는 한 나는 오독 것,그것이 제안하는 그것에 대해 유효한 컴파일러를 추가하는 그것에 새로운 배치뿐만 아니라:

이러한 오버헤드이 적용될 수 있습에서 모든 배열 새로운 표정을 포함하여,그 참조는 라이브러리 함수 연산자는 새로운[](std::size_t,void*)및 다른 위치는 할당 기능이 있다.금액의 오버헤드 달라질 수 있습 중 하나에서 호출의 새로운다.

는 말했다,나는 생각한 VC 유일하는 컴파일러를 나에게 문제가 이와 함께,그것을 밖으로,GCC,Codewarrior 및 ProDG.나는 다시 확인해야 합니다,하지만.

답변 주셔서 감사합니다.를 사용하여 배치를 위한 새로운 배열의 각 항목이었는 솔루션을 사용하여 종료될 때 나는 이것으로(죄송해 언급했는 질문에).나는 단지는 느낌 있어야합니다 내가 누락되었고 그것에 대해 배치 새[].그것은,그것은 보인다 같은 위치는 새로운[]은 본질적으로 사용할 수 없는 감사의 기준 수 있도록 컴파일러를 추가 지정되지 않은 오버헤드를 저장할 수 없습니다.나는 볼 수 없는 방법을 안전하게 사용하고 portably.

난지도 정말 이유는 분명 그의 요구가 데이터는,당신을 삭제[]배열에 어쨌든,그래서지 않아요 완전히 왜 그것을 알아야 얼마나 많은 항목에 있습니다.

@James

난지도 정말 이유는 분명 그의 요구가 데이터는,당신을 삭제[]배열에 어쨌든,그래서지 않아요 완전히 왜 그것을 알아야 얼마나 많은 항목에 있습니다.

후에게 이 일을 생각,내가 당신에 동의합니다.이유가 없는 배치해야를 저장하는 데 필요한 요소의 수가 없기 때문에 배치 삭제합니다.터가 존재하지 않기 때문에 배치 삭제,거기에 아무 이유 없이 배치를 위한 새로운 수를 저장하기 위해 요소입니다.

또한 이 테스트 gcc Mac 에서 사용하여 클래스와 소멸자.시스템에서,새로운 배치되었 변경하면 포인터이다.이는 경우 이 VC++문제이며,이를 위반할 수 표준(표준하지 않는 특히 주소이다,그래서 멀리 찾을 수 있습니).

위치 자체가 새로운 휴대용하지만,가정을 만들에 대한 그것이 무엇으로 지정된 블록의 메모리하지 않은 휴대용입니다.다음과 같은 무엇이었다 말하기,당신이 컴파일러와 주어진 덩어리의 메모리,어떻게 알 수 있는 방법을 배열을 할당하고 적절하게폭 각 요소가 했던 모든 포인터가?(참조하십시오 인터페이스의 연산자를 삭제[].)

편집:

과 실제적으로 배치 삭제만 그 때 생성자 예외가 발생하는 배열을 할당하는 배치 새[].

는지 여부를 새로운[]실제로 요구하는 추적 요소의 수를 어떻게든 무언가가 남아 있는 표준에는 나뭇잎은 그것을 컴파일러입니다.불행하게도,이 경우.

내가 생각하는 gcc 는 것과 같습니다 MSVC 지만,물론 이하지 않 그것은"휴대용".

내가 생각하는 작업할 수 있습니다 문제를 해결할 때 NUMELEMENTS 은 참으로 컴파일한 시간 상수처럼,그래서:

typedef A Arr[NUMELEMENTS];

A* p = new (buffer) Arr;

이 사용해야 하는 스칼라 새로운 배치.

비슷한 방법을 사용하는 것이 하나의 요소 계산하기 위한 하나 배치-새로운 배열을 사용하여 이러한 요소의 크기를 계산하기 위해 필요한 훌륭한 기능들을 가지고 있습니다.

필요할 경우 크기에 대한 다른 계산에는 요소의 수를 알려지지 않을 수도 사용할 수 있습 sizeof(A[1])곱하여 당신의 필수 요소 계산합니다.

e.g

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

for(int i = 0; i < NUMELEMENTS; ++i)
{
    pA[i] = new (pA + i) A();
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top