检测到glibc - 双重免费或腐败(!prev)

时间:2014-10-22 06:01:41

标签: c

我收到你在标题中看到的错误,我无法弄清楚原因。

代码:

#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;
}

所以我认为错误是由char *操作引起的,但我不知道为什么。

我想要做的是我希望可以将字符串作为参数传递给data->setAdr,我希望之后将其分配给变量。

编译行:

gcc -o test main.cpp

2 个答案:

答案 0 :(得分:2)

data->setAdr(data, "asdasd");存在问题。

您正在设置未由malloc分配的内存块的地址,稍后尝试使用free释放它。除了NULL指针之外释放这些内存块(不是由malloc分配)会导致未定义的行为。

在您的情况下,这也至少泄漏了255个字节的内存。在这种情况下,valgrind可以帮助您更好地理解。

更改以下功能应解决此问题(适当地重命名)

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

答案 1 :(得分:1)

问题在于:

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

您的实施是:

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

因此,您使用指向常量字符串的指针覆盖以前的malloc()内存的地址,因此当您执行data->del(data);时,glibc会警告您正在释放内存未分配,加上先前分配的内存丢失。请尝试改为:

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

请记住添加合适的错误检查等等!