2013-07-06 3 views
3

없이 무료 더블, 은 무엇 동적 메모리 할당을 포함하지 않는 것입니다 프로그램에서 더블 자유를 일으킬 수 있을까?는 동적 메모리 할당 일반적으로

정확하게 말해서 코드 중 어느 것도 동적 할당을 사용하지 않습니다. 나는 STL을 사용하고있다. 그러나 G ++/glibc/STL의 깨어진 implmentation보다 내가 잘못한 일이 될 가능성이 훨씬 더 높다.

나는이에 대한 답을 찾기 위해 노력하고 주위에 검색 한, 그러나 나는 동적 메모리 할당없이 생성되는이 오류의 예를 찾을 수 없습니다.

나는이 오류를 생성 된 코드를 공유하고 싶지만, 내가 그것을 해제 할 수 없습니다 그리고 난 여기에 주어진 수있을 정도로 작은 뭔가 문제를 감소하는 방법을 모르겠어요. 내 코드가하는 일의 요지를 설명하기 위해 최선을 다할 것입니다.

함수를 떠날 때 오류가 발생했으며 스택 추적은 그것이 소멸자 std::vector<std::set<std::string>>에서 나온 것으로 나타났습니다. 벡터의 일부 요소 수가 emplace_back()에 의해 초기화되고있었습니다. 마지막 도랑 시도에서, 나는 push_back({{}})으로 바꾸었고 문제는 사라졌습니다. 환경 변수를 설정하여 문제를 피할 수도 있습니다 MALLOC_CHECK_ = 2. 내 이해에 의해, 그 환경 변수는 glibc가 오류를 없애기보다는 더 많은 정보로 중단되도록 야기했을 것입니다.

이 질문은 단지 내 호기심을 제공하기 위해 요구되는, 그래서 어두운 대답 슈팅을 해결합니다. 컴파일러 버그 였지만, it's always my fault이라는 것이 나왔습니다.

답변

3

일반적으로 동적 메모리 할당을 포함하지 않는 프로그램에서 이중 자유를 유발할 수있는 요인은 무엇입니까? 일반적으로

동적으로 메모리를 할당하지만 난 "이중으로 이끌었다 만든 오류를 보여주는 rule of three

struct Type 
{ 
    Type() : ptr = new int(3) { } 
    ~Type() { delete ptr; } 
    // no copy constructor is defined 
    // no copy assign operator is defined 

private: 
    int * ptr; 
}; 

void func() 
{  
    { 
    std::vector<Type> objs; 
    Type t; // allocates ptr 
    objs.push_back(t); // make a copy of t, now t->ptr and objs[0]->ptr point to same memory location 
    // when this scope finishes, t will be destroyed, its destructor will be called and it will try to delete ptr; 
    // objs go out of scope, elements in objs will be destroyed, their destructors are called, and delete ptr; will be executed again. That's double free on same pointer. 
    }  
} 
+1

나는 3 개의 규칙에 관한 많은 질문과 기사를 발견했다. 그러나 귀하의 답변을 포함하여 모두 새로운 내용의 전화와 삭제가 필요했습니다. 나는 복사 생성자와 대입 연산자를 추가하는 것이 내 문제를 해결할 것이라고 믿고 싶지만 내 질문은 왜 그런가? 동적으로 멤버를 할당 한 클래스에서는 모든 것을 스택에 넣을 때가 아니라 어떤 일이 발생할 수 있는지 이해합니다. –

1

내가 흉 예를 추출 따르지 않는 형태의 복사본을 만들 무료 또는 손상 "런타임 오류. 구조체는 동적 메모리 할당을 명시 적으로 사용하지 않지만 내부적으로 std :: vector는 내용이 더 많은 항목을 수용 할 수 있도록 커질 수 있으므로이를 참고하십시오. 그러므로이 문제는 '원칙 3'원칙을 위반하지 않으므로 진단하기가 약간 어려웠습니다.

#include <vector> 
#include <string.h> 

typedef struct message { 
    std::vector<int> options; 
    void push(int o) { this->options.push_back(o); } 
} message; 

int main(int argc, const char* argv[]) 
{ 
    message m; 
    m.push(1); 
    m.push(2); 

    message m_copy; 
    memcpy(&m_copy, &m, sizeof(m)); 
    //m_copy = m; // This is the correct method for copying object instances, it calls the default assignment operator generated 'behind the scenes' by the compiler 
} 

때()는 표준 : : 벡터 소멸자를 호출하는 m_copy가 파괴 돌려 주. m 객체가 소멸 될 때 이미 해제 된 메모리를 삭제하려고 시도합니다.

아이러니하게도, 나는 실제로 시도하고 '딥 카피'를 달성하기 위해 방어 적이기를 사용했다. 이것은 내 잘못이있는 곳입니다. 내 생각 엔 할당 연산자를 사용하면 message.options의 모든 멤버가 실제로 "새로 할당 된 메모리"에 복사되지만 memcpy는 컴파일 타임에 할당 된 멤버 (예 : uint32_t 크기 멤버) 만 복사합니다. Will memcpy or memmove cause problems copying classes?을 참조하십시오. 분명히 이것은 비 기본형 멤버가있는 구조체에도 적용됩니다 (여기서는 마찬가지입니다).

아마 당신은 또한 아마 당신은하지 않았다, 잘못 표준 : : 벡터를 복사하여 같은 동작을 보았다. 결국 그것은 내 잘못이었습니다 :).