Ошибка неверного указателя при вызове free () после malloc в C - PullRequest
0 голосов
/ 14 февраля 2019

Я делаю очень простую практику динамического размещения в C, и я столкнулся с этой проблемой: когда я пытаюсь вызвать free() с указателем, возвращенным malloc(), я получаю ошибку неверного указателя во время выполнения.

Когда я удаляю free() из кода, он работает нормально.Указатель, который я использую, не изменяется в любом случае после того, как возвращается malloc (кроме преобразования).Так что это исключает некоторые предложения, которые я нашел в Интернете.Ниже мой код:

#include <stdio.h>
#include <stdlib.h>

int main() {
        int num = 0;
        //printf("Enter a number: ");
        //scanf("%d", &num);
        char* p = (char*)malloc(16*sizeof(char));
        printf("%p", p);
        if(p) {
                p = "mark";
                printf("\n%s\n", p);
                free(p); //when removed no error
        }
        return 0;
}

Ниже приведено сообщение об ошибке:

0xa26010
mark
*** Error in `./a.out': free(): invalid pointer: 0x00000000004006b7 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fa968aed7e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fa968af637a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fa968afa53c]
./a.out[0x40061a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fa968a96830]
./a.out[0x4004e9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 6815746                            /home/kushal/Documents/GATE/prac_C/a.out
00600000-00601000 r--p 00000000 08:03 6815746                            /home/kushal/Documents/GATE/prac_C/a.out
00601000-00602000 rw-p 00001000 08:03 6815746                            /home/kushal/Documents/GATE/prac_C/a.out
00a26000-00a47000 rw-p 00000000 00:00 0                                  [heap]
7fa964000000-7fa964021000 rw-p 00000000 00:00 0 
7fa964021000-7fa968000000 ---p 00000000 00:00 0 
7fa968860000-7fa968876000 r-xp 00000000 08:03 39719295                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa968876000-7fa968a75000 ---p 00016000 08:03 39719295                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa968a75000-7fa968a76000 rw-p 00015000 08:03 39719295                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7fa968a76000-7fa968c36000 r-xp 00000000 08:03 39714902                   /lib/x86_64-linux-gnu/libc-2.23.so
7fa968c36000-7fa968e36000 ---p 001c0000 08:03 39714902                   /lib/x86_64-linux-gnu/libc-2.23.so
7fa968e36000-7fa968e3a000 r--p 001c0000 08:03 39714902                   /lib/x86_64-linux-gnu/libc-2.23.so
7fa968e3a000-7fa968e3c000 rw-p 001c4000 08:03 39714902                   /lib/x86_64-linux-gnu/libc-2.23.so
7fa968e3c000-7fa968e40000 rw-p 00000000 00:00 0 
7fa968e40000-7fa968e66000 r-xp 00000000 08:03 39714844                   /lib/x86_64-linux-gnu/ld-2.23.so
7fa969046000-7fa969049000 rw-p 00000000 00:00 0 
7fa969064000-7fa969065000 rw-p 00000000 00:00 0 
7fa969065000-7fa969066000 r--p 00025000 08:03 39714844                   /lib/x86_64-linux-gnu/ld-2.23.so
7fa969066000-7fa969067000 rw-p 00026000 08:03 39714844                   /lib/x86_64-linux-gnu/ld-2.23.so
7fa969067000-7fa969068000 rw-p 00000000 00:00 0 
7ffcf8e4b000-7ffcf8e6c000 rw-p 00000000 00:00 0                          [stack]
7ffcf8f1d000-7ffcf8f20000 r--p 00000000 00:00 0                          [vvar]
7ffcf8f20000-7ffcf8f22000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)

Ответы [ 4 ]

0 голосов
/ 14 февраля 2019

В вашем коде есть ошибка:

 p = "mark";

неверен, p - указатель, т.е. предполагается, что он содержит значение адреса.Вы не можете присвоить ему строку.Вы должны использовать функции, предоставляемые стандартной библиотекой, такие как strcpy или strncpy (заголовок: string.h).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
        int num = 0;
        //printf("Enter a number: ");
        //scanf("%d", &num);
        char* p = (char*)malloc(16*sizeof(char));
        printf("%p", p);
        if(p) {
                //*p = st"mark\0";
                strcpy(p, "mark");
                printf("\n%s\n", p);
                free(p); //when removed no error
        }
        return 0;
}
0 голосов
/ 14 февраля 2019

Вам не нужно выделять память для char Я думаю, просто объявите это, и когда компилятор преобразует его в сборку, он сделает свое волшебство

Я думаю, что у вас включен какой-то режим отладки

, если вы хотите попробовать malloc(), попробуйте сначала int s

int *ptr; 
ptr = malloc(sizeof(int));
ptr = 20;
printf("%d", ptr);
ptr = NULL;
free(ptr);
return 0;

с массивами символов, которые вы просто делаете char *description;, и вы можете сделать description = "hello world" (без звездочки).

если вы хотите напечатать указатель на массив символов, просто наберите printf("%s", description);

0 голосов
/ 14 февраля 2019

Проблема в том, что p не указывает на память, выделенную с помощью malloc().Вместо этого он содержит указатель на константу "mark", поэтому в основном вы пытаетесь удалить литерал, который не разрешен

int main() {
        int num = 0;
        //printf("Enter a number: ");
        //scanf("%d", &num);
        char* p = (char*)malloc(16*sizeof(char));
        printf("%p", p);
        if(p) {
                strcpy(p,"mark");
                printf("\n%s\n", p);
                free(p); //when removed no error
        }
        return 0;
}

использование strcpy решит проблему

0 голосов
/ 14 февраля 2019

У вас есть переменная p, которая указывает на память, возвращаемую malloc.Затем вы изменяете переменную p, чтобы она указывала на память, занятую строковым литералом «mark».Когда вы пытаетесь delete это, вы пытаетесь удалить строковый литерал.

Короче говоря, строка p = "mark" не делает то, что вы думаете, она делает.Он не копирует это значение в память, возвращаемую malloc.

Попробуйте изменить эту строку на strcpy(p, "mark"), и я подозреваю, что все начнет работать лучше.

(При этом я не долженЯ даже не упоминаю strcpy, потому что это так небезопасно, и есть альтернативы, которые предотвратят проблемы переполнения буфера. Но это отдельный вопрос, и здесь много разговоров об этом на SO.)

...