Malloc, свободный и ошибка сегментации - PullRequest
6 голосов
/ 08 октября 2010

Я не понимаю, почему в этом коде вызов "free" вызывает ошибку сегментации:

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

char *char_arr_allocator(int length);

int main(int argc, char* argv[0]){

    char* stringa =  NULL;
    stringa = char_arr_allocator(100);  
    printf("stringa address: %p\n", stringa); // same address as "arr"
    printf("stringa: %s\n",stringa);
    //free(stringa);

    return 0;
}

char *char_arr_allocator(int length) {
    char *arr;
    arr = malloc(length*sizeof(char));
    arr = "xxxxxxx";
    printf("arr address: %p\n", arr); // same address as "stringa"
    return arr;
}

Может мне кто-нибудь объяснить это?

Спасибо, Segolas

Ответы [ 4 ]

15 голосов
/ 08 октября 2010

Вы выделяете память, используя malloc правильно:

arr = malloc(length*sizeof(char));

, затем вы делаете это:

arr = "xxxxxxx";

это приведет к тому, что arr будет указывать на адрес строкилитерал "xxxxxxx", утечка ваша malloc ed память.А также вызов free для адреса строкового литерала приводит к неопределенному поведению.

Если вы хотите скопировать строку в выделенную память, используйте strcpy как:

strcpy(arr,"xxxxxxx");
2 голосов
/ 08 октября 2010

Когда вы пишете постоянную строку в C, например, "xxxxxx", происходит то, что эта строка попадает непосредственно в исполняемый файл.Когда вы ссылаетесь на него в вашем источнике, он заменяется указателем на эту память.Таким образом, вы можете прочитать строку

 arr = "xxxxxxx";

, рассматривая arr как число как что-то вроде:

 arr = 12345678;

Где этот номер - адрес.malloc вернул другой адрес, и вы выбросили его, когда назначали новый адрес для обр.Вы получаете segfault, потому что вы пытаетесь освободить постоянную строку, которая находится непосредственно в вашем исполняемом файле - вы никогда не выделяли ее.

2 голосов
/ 08 октября 2010

Третья строка char_arr_allocator() стирает результат malloc() и заменяет его фрагментом статической памяти на странице данных.Вызов free() при этом взрывается.

Используйте str[n]cpy(), чтобы вместо этого скопировать строковый литерал в буфер.

0 голосов
/ 08 октября 2010

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

...