문제

프로그래밍 스타일과 디자인을 무시하면 스택에 할당 된 가변으로 삭제를 호출하는 것이 "안전한"입니까?

예를 들어:

   int nAmount;
   delete &nAmount;

또는

class sample
{
public:
    sample();
    ~sample() { delete &nAmount;}
    int nAmount;
}
도움이 되었습니까?

해결책

아니, 전화하는 것은 안전하지 않습니다 delete 스택-할당 변수에서. 당신은 만 전화해야합니다 delete 창조 된 것들에 new.

  • 각각 malloc 또는 calloc, 정확히 하나가 있어야합니다 free.
  • 각각 new 정확히 하나가 있어야합니다 delete.
  • 각각 new[] 정확히 하나가 있어야합니다 delete[].
  • 각 스택 할당에 대해 명시 적 자유 또는 삭제가 없어야합니다. 파괴자는 해당되는 경우 자동으로 호출됩니다.

일반적으로, 당신은 이들 중 하나를 혼합하고 일치시킬 수 없습니다. free-ing 또는 delete[]-a new 물체. 그렇게하면 정의되지 않은 동작이 발생합니다.

다른 팁

글쎄, 시도해 봅시다 :

jeremy@jeremy-desktop:~$ echo 'main() { int a; delete &a; }' > test.cpp
jeremy@jeremy-desktop:~$ g++ -o test test.cpp
jeremy@jeremy-desktop:~$ ./test
Segmentation fault

따라서 분명히 그것은 전혀 안전하지 않습니다.

새로운 (또는 해당 물질에 대한 Malloc)를 사용하여 메모리 블록을 할당하면 할당 된 실제 메모리 블록이 요청한 것보다 클 것입니다. 메모리 블록에는 부기 정보가 포함되어 있으므로 블록을 풀면 무료 풀에 쉽게 다시 넣고 인접한 자유 블록으로 합쳐질 수 있습니다.

새로운 것으로부터받지 못한 메모리를 해방 시키려고 할 때, 부기 정보는 거기에 없을 것이지만 시스템은 그대로 작동하며 결과는 예측할 수 없을 것입니다 (일반적으로 나쁘다).

예, 그것은 정의되지 않은 행동입니다 delete 오지 않은 모든 것 new IS UB :

C ++ 표준, 섹션 3.7.3.2.3 : 표준 라이브러리에 제공된 THEA 거래 기능 중 하나에 제공되는 첫 번째 인수의 값은 null 포인터 값; 그렇다면 거래 기능이 표준 라이브러리에 제공된 경우 거래 기능에 대한 호출은 영향을 미치지 않습니다. 그렇지 않으면 공급 된 값입니다 operator delete(void*) 표준 라이브러리에서는 이전의 호출에 의해 반환 된 값 중 하나가되어야합니다. operator new(std::size_t) 또는 operator new(std::size_t, const std::nothrow_t&) 표준 라이브러리에서.

정의되지 않은 행동의 결과는 정의되지 않았습니다. "아무것도 일어나지 않는다"는 다른 것만 큼 유효한 결과입니다. 그러나 일반적으로 "아무것도 일어나지 않는다". 유효하지 않은 메모리 블록을 처리하면 할당 자에 대한 후속 호출에서 심각한 결과가 발생할 수 있습니다.

Windows에서 G ++ 4.4에서 약간 플레이 한 후 매우 흥미로운 결과를 얻었습니다.

  1. 스택 변수에서 삭제를 호출하는 것은 아무것도하지 않는 것 같습니다. 오류가 발생하지 않지만 삭제 후 문제없이 변수에 액세스 할 수 있습니다.

  2. 방법이있는 수업이 있습니다 delete this 히프에 할당 된 경우 객체를 성공적으로 삭제하지만 스택에 할당 된 경우 (스택에 있으면 아무 일도 일어나지 않습니다).

아무도 무슨 일이 일어나는지 알 수 없습니다. 이것은 정의되지 않은 행동을 불러 일으키므로 말 그대로 어떤 일이 일어날 수 있습니다. 이것을하지 마십시오.

아니요, 새로 사용하여 할당 된 메모리는 삭제 연산자를 사용하여 삭제해야하며 Malloc을 사용하여 할당 된 것은 무료를 사용하여 삭제해야합니다. 그리고 스택에 할당 된 변수를 처리 할 필요가 없습니다.

천사는 날개를 잃습니다 ... 당신은 delete 포인터에 할당 된 포인터에 new, 그렇지 않으면 정의되지 않은 동작이됩니다.

여기서 메모리는 스택을 사용하여 할당되므로 익살로 삭제할 필요가 없지만 동적으로 모든 코팅 된 경우

int *a = new int ()처럼

그런 다음 메모리가 무료 상점에서 할당되기 때문에 삭제 및 삭제 & A (A 자체는 포인터)를 삭제해야합니다.

당신은 이미 질문에 직접 대답했습니다. delete 이를 통해 포인터에만 사용해야합니다 new. 다른 일을하는 것은 평범하고 단순한 정의되지 않은 행동입니다.

그러므로 실제로 무슨 일이 일어나는지는 말할 수 없으며, 코드에서 충돌을 통해 하드 드라이브를 지우는 것까지 잘 작동하는 것은이 작업의 유효한 결과입니다. 그러니 제발 절대 그렇게하지 마십시오.

New와 동적으로 할당되지 않은 항목에서 Delete를 호출해서는 안되기 때문에 UB입니다. 그렇게 간단합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top