2014-10-22 2 views
1

제목에서 볼 수있는 오류가 발생하며 그 이유를 알 수 없습니다.glibc가 감지되었습니다. 이중 무료 또는 손상 (! prev)

코드 :

#include <cstdlib> 
#include <cstdio> 

struct CData { 
    int* num; 
    char* adr; 
    char* ph; 

    void (*init)(CData* owner); 
    void (*del)(CData* owner); 
    char* (*getAdr)(CData* owner); 
    void (*setAdr)(CData* owner, char* adr); 
}; 

void CData_init(CData* owner) { 
    owner->num = (int*)malloc(sizeof(int)); 
    owner->adr = (char*)malloc(sizeof(char)*255); 
    owner->ph = (char*)malloc(sizeof(char)*255); 
} 

void CData_del(CData* owner) { 
    free(owner->num); 
    free(owner->adr); 
    free(owner->ph); 
} 

char* CData_getAdr(CData* owner) { 
    return owner->adr; 
} 

void CData_setAdr(CData* owner, char* adr) { 
    owner->adr = adr; 
} 

int main() { 
    CData* data = (CData*)malloc(sizeof(CData)); 

    data->init = CData_init; 
    data->del = CData_del; 
    data->getAdr = CData_getAdr; 
    data->setAdr = CData_setAdr; 

    data->init(data); 

    data->setAdr(data, "asdasd"); 
    printf("%d", data->getAdr(data)); 

    data->del(data); 

    free(data); 

    return 0; 
} 

그래서 나는 오류가 문자 * 조작에 의해 발생합니다 생각하지만 난 그 이유를 모른다.

내가 원하는 것은 문자열을 매개 변수로 data->setAdr에 전달하고 나중에 변수에 할당되기를 원합니다.

컴파일 라인 :

gcc -o test main.cpp 
+0

"double free"- 무언가를 알려주고, 아마도 double과 같은 것이어야합니다. free()' " – bitcell

+0

문자열 리터럴을 비울 수 없습니다. (그리고 당신은'setAdr'에 이전 값을 유출하고 있습니다.) – Mat

+0

예, 처음에 그렇게 추측했는데, 어디에서? – ohyou

답변

2

data->setAdr(data, "asdasd");는 문제가있다.

malloc에서 할당하지 않은 메모리 블록의 주소를 설정하고 나중에 free을 사용하여 해제하려고합니다. NULL 포인터를 제외하고 그러한 메모리 블록 (malloc에 ​​의해 할당되지 않음)을 해제하면 정의되지 않은 동작이 발생합니다.

이 경우에도 최소한 255 바이트의 메모리가 누출됩니다. valgrind은이 경우 더 잘 이해할 수 있도록 도와줍니다.

data->setAdr(data, "asdasd"); 

귀하의 구현은 다음과 같습니다 :

변경 다음 함수는이 문제는 여기에있다

void CData_setAdr(CData* owner, char* adr) { 
    strcpy(owner->adr, adr); /* include cstring */ 
} 
+0

제 경우에는 단순히 포인터를 정적 문자열로 바꾸고 메모리 할당에 신경 쓰지 않으시겠습니까? – ohyou

+0

그럴 경우, 문자열의 소유권을'CData'에게주지 말아야하며 setter는 문자열을 할당하고 해제해야합니다. 모듈간에 할당 및 무료 규칙을 혼합 할 수 없습니다. 두 설정 방법을 모두 사용하려면 해제 할 시간과 해제하지 않을 시간을 감지하는 약간 더 많은 프레임 워크가 필요합니다. –

+0

알겠습니다. 고마워요. – ohyou

1

(적절하게 이름 변경) 수정해야합니다 그래서

void CData_setAdr(CData* owner, char* adr) { 
    owner->adr = adr; 
} 

, 당신은 덮어 이전에 -에 대한 포인터가있는 메모리 nstant 문자열이므로 data->del(data);을 수행하면 glibc은 할당되지 않은 메모리를 해제하고 이전에 할당 된 메모리가 손실된다는 경고 메시지가 표시됩니다. 대신 다음을 시도하십시오 :

void CData_setAdr(CData* owner, char* adr) { 
    strcpy(owner->adr, adr); 
} 

적절한 오류 검사 등을 추가해야합니다!

+0

나도 안다. 고마워. – ohyou

관련 문제