Обнаружен glibc ./.a.out: free (): неверный указатель - PullRequest
0 голосов
/ 22 февраля 2011
typedef struct _PERSON
{
        size_t age;
        unsigned char* name;
}PERSON;

int init(PERSON** person)
{
        (* person) = (PERSON *) malloc(sizeof(struct _PERSON));
        (* person)->age = 1;
        (* person)->name = (unsigned char *) malloc(sizeof(4));
        (* person)->name = "NAME";

        return 0;
}

void close(PERSON** person)
{
        (* person)->age = 0;
        if((* person)->name != NULL)
        {
                free((* person)->name);
        }

        if((* person) != NULL)
        {
                free((* person));
        }
}

int main(int argc, char* argv[])
{
        PERSON* p;

        init(&p);

        printf("%d\t%s\n", (int) p->age, p->name);

        close(&p);

        return 0;
}

1       NAME
*** glibc detected *** ./a.out: free(): invalid pointer: 0x000000000040079c ***
======= Backtrace: =========
/lib/libc.so.6(+0x774b6)[0x7fa9027054b6]
/lib/libc.so.6(cfree+0x73)[0x7fa90270bc83]
./a.out(close+0x3d)[0x400651]
./a.out[0x40069f]
/lib/libc.so.6(__libc_start_main+0xfe)[0x7fa9026acd8e]
./a.out[0x4004f9]

...

7fa8fc000000-7fa8fc021000 rw-p 00000000 00:00 0
7fa8fc021000-7fa900000000 ---p 00000000 00:00 0
7fa902478000-7fa90248d000 r-xp 00000000 08:12 23068732                   /lib/libgcc_s.so.1
7fa90248d000-7fa90268c000 ---p 00015000 08:12 23068732                   /lib/libgcc_s.so.1
7fa90268c000-7fa90268d000 r--p 00014000 08:12 23068732                   /lib/libgcc_s.so.1
7fa90268d000-7fa90268e000 rw-p 00015000 08:12 23068732                   /lib/libgcc_s.so.1
7fa90268e000-7fa902808000 r-xp 00000000 08:12 23068970                   /lib/libc-2.12.1.so
7fa902808000-7fa902a07000 ---p 0017a000 08:12 23068970                   /lib/libc-2.12.1.so
7fa902a07000-7fa902a0b000 r--p 00179000 08:12 23068970                   /lib/libc-2.12.1.so
7fa902a0b000-7fa902a0c000 rw-p 0017d000 08:12 23068970                   /lib/libc-2.12.1.so
7fa902a0c000-7fa902a11000 rw-p 00000000 00:00 0
7fa902a11000-7fa902a31000 r-xp 00000000 08:12 23068966                   /lib/ld-2.12.1.so
7fa902c25000-7fa902c28000 rw-p 00000000 00:00 0
7fa902c2e000-7fa902c31000 rw-p 00000000 00:00 0
7fa902c31000-7fa902c32000 r--p 00020000 08:12 23068966                   /lib/ld-2.12.1.so
7fa902c32000-7fa902c33000 rw-p 00021000 08:12 23068966                   /lib/ld-2.12.1.so
7fa902c33000-7fa902c34000 rw-p 00000000 00:00 0
7fff442d5000-7fff442f6000 rw-p 00000000 00:00 0                          [stack]
7fff44308000-7fff44309000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

Ответы [ 3 ]

2 голосов
/ 22 февраля 2011

(* person)->name = (unsigned char ) malloc(sizeof(4)); (* person)->name = "NAME"

Здесь вы запрашиваете память, а затем теряете указатель на эту память. (Вы указываете на «NAME», которое не было выделено malloc.) Вот почему, когда вы пытаетесь free указатель, вы получаете ошибку.

2 голосов
/ 22 февраля 2011

Проблема в этом утверждении ( *person)->name = "NAME";. Это не копирует строку "NAME" в переменную name. Вместо этого name указывает на другую область памяти (а не на malloc, указанную вами). Если вы попытаетесь free этой памяти, вы получите неопределенное поведение. Вам нужно использовать strcpy (или strncpy), чтобы скопировать строку в переменную name. В настоящее время вы делаете malloc(sizeof(4)), что не правильно. Помните, что вам нужно выделить символы no.of + 1 символ для строк, чтобы в конце поместился символ NULL, в настоящее время вы выделили только 4 символа, что недостаточно, вам нужно выделить память для 5 символов. Так что вам нужно сделать malloc(sizeof(char)*5).

0 голосов
/ 22 февраля 2011

Также взгляните на calloc: calloc

Позволяет выделить n членов указанного размера. Возможно, это помогает думать о проблеме.

...