2011-01-10 7 views
1

업데이트 : (솔벤트) 업데이트 : 좋아요, 나는 완전 바보입니다! 내 메인 프로그램에서 "데이터로 처리"부분에서 포인터가 증가되어 결국 분명히 작동하지 않을 것입니다! D' oh! 다른 공유 라이브러리에 할당 된 포인터 삭제

그래서 나는이 유사한 기능 (슈퍼 단순화보기)가 공유 라이브러리를 컴파일하고,이 라이브러리는 mine- 그래서 데이터가 할당되는 방법을 알고있다 :

그것은 반환해야
// inside library 

void* getData(int size) { // with other parameters 

    UINT8* data = new UINT8[size]; // where typedef uint8_t UINT8; for gcc 

    // do a socket read, where data is the buffer 
    blockingRead (someSocket, data, propertySize); 

    return (void*) data; 
} 

void 포인터 (데이터가 struct 일 수 있으므로 struct에 그냥 캐스트 할 수 있음).

문제는 내 주 프로그램에서이 포인터를 사용하고 있는데, 끝나면 삭제하려고합니다. 내 메인 프로그램에서이 작업을 수행하는 경우 :

// inside library 

void disposeData(void* data) { // call this from main program 
    delete[] (UINT8*) data; // cast it back to the original type of pointer 
} 

을하지만 난 여전히 같은 충돌을 얻을 :

// inside main program 
char* data = (char*) Library::getData(5); 
// do stuff with data 

delete[] data; // crashes with: 
// *** glibc detected *** core: free(): invalid pointer: 0x00002aaab007bca4 *** 

나는 어쩌면 생각 나는 대신 공유 라이브러리에서 삭제해야합니다! 삭제를하지 않으면 모든 것이 잘 작동하지만 멋지게 메모리 누수가 발생하지 않습니다.

나는 아마 어딘가에 바보 같은 짓을하고있다. 내 방식으로 오류를 찾도록 도와주세요!

편집 : 의견에서 지적한대로 위의 코드가 작동하는 것 같습니다. 특히 코드에서 오류의 원인이 무엇인지 확인해야합니다.

+1

문제가있는 최소한의 예를 만들어야한다고 생각합니다. 나는 g ++로 당신의 코드를 시험해 보았다. –

+0

감사합니다 노아! 흠, 거기에 더있을 것 같아요 ... 조사 할게요 –

+1

당신의 문제는'data stuff with data' 부분에있을 가능성이 높습니다. 당신은 어떻게 든'Library :: getData (5)'가 반환하는 것과 같은 포인터를 삭제하지 않을 것입니다 (아마 버퍼 오버런 때문이거나 어딘가에서'data'에 다른 것을 할당 할 것입니다) – nos

답변

0

라이브러리가 할당 된 포인터를 제공하는 경우 할당 취소하는 방법을 설명해야합니다. 할당 해제를위한 자체 기능을 제공 할 수 있습니다. 라이브러리에 대한 소스 코드가없고 포인터를 만들 때 new[]을 사용하는지 확인하지 않는 한 메모리를 할당하는 방법을 확신 할 수 없습니다. deallocator가 할당 자와 일치하지 않기 때문에 충돌이 일어날 가능성이 큽니다.

0

대신 스마트 포인터와 같은 RAII 기반 디자인을 사용하는 것이 어떻습니까? Boost 스마트 포인터는 아주 잘 설계되었습니다.

2

valgrind을 사용해 보셨습니까? valgrind를 사용하면 문제의 원인이 될 수있는 다양한 메모리 관리 오류를 정확히 찾아내는 데 도움이됩니다. 보고있는 오류는 힙 손상 (@nos가 아마도 do stuff 부분에서 말한 것처럼) 또는 원래 할당했던 동일한 객체를 실제로 해제하지 않은 것처럼 보입니다. 당신은 "캐스트"를 언급으로

0

나는, 당신이 그런 일을하고있는 내기 :

#include <stdio.h> 

class B { int x; }; 

class C { int y; }; 

class A : public B, public C { }; 

void* getData() 
{ 
    A* a = new A(); 
    printf("%p\n", a); 
    C* c = a; 
    printf("%p\n", c); 
    return c; 
} 

void deleteData(void* x) 
{ 
    // delete (A*)x; // incorrect; causes crash 
    delete (A*)(C*)x; // correct 
} 

int main() 
{ 
    void* x = getData(); 
    deleteData(x); 
    return 0; 
} 

이 컴파일러는 허리 뒤에 포인터 연산에 죄 캐스트 모양을 번역 할 수있다 조심하십시오.

관련 문제