освобождение выделенной области кучи с помощью функции, выполняемой ошибкой сегментации бросков pthred - PullRequest
1 голос
/ 08 декабря 2010
void *do_chld(void *arg)
{
    char *sub; 
    sub = malloc(255 * sizeof(char));

    /*
        ------ Some Code ----
    */ 

    free(sub);
    pthread_exit((void *)0);
}

Вышеуказанная функция передается в pthreads.Когда программа выполняется, я получаю ошибку сегментации.Как только я комментирую вызов free(sub), мой код работает нормально.Я не могу понять, почему?Не можем ли мы динамически освободить память в потоках?Поскольку куча является общей для всех одноранговых потоков, связанных с основным потоком.

Редактировать 1 - полный код

void *do_chld(void *arg)
{

    int     new_fd = (int) arg;
    int     i,n,val;
    char buf[255];
    char *sub; 


    sub = malloc(255 * sizeof(char));

    printf("Child thread [%d]: Socket number = %d\n", pthread_self(), new_fd);

    /* read from the given socket */
    n = read(new_fd,buf,100);
    if(n<0){
            fprintf(stderr,"Receieving Failed\n");
            exit(2);
    }
    //process
    printf("Received %s \n",buf);

    val = checkSpelling(buf) ; 
    if(val){
        sub = "Correct Spelling";
    }
    else{
        sub = "InCorrect Spelling";

    }
    n = 0 ; 

    n = write(new_fd,sub,strlen(sub));
    if(n<0){
        fprintf(stderr,"Sending Failed\n");
        exit(2);
    }   


    /* close the socket and exit this thread*/
    close(new_fd);
        free(sub);
    pthread_exit((void *)0);
}

Ответы [ 3 ]

3 голосов
/ 08 декабря 2010

Вы присваиваете строковый литерал - строки «Правильное написание» / «Неправильное написание» - указателю sub, а затем пытаетесь освободить его с помощью free().Строковые литералы размещаются в коде статически и не могут быть освобождены.

По сути, указатель sub во время вызова free() указывает на то, что не было выделено с malloc().

Я думаю, что главная проблема заключается в том, что вы выполняете присваивание указателя, когда вы, вероятно, хотите сделать строку copy , чтобы содержимое строки находилось в той области, из которой вы получилиmalloc().

РЕДАКТИРОВАНИЕ:

Возможно, вы захотите взглянуть на функции strcpy() и strdup().strcpy() было бы хорошо в вашем случае, хотя было бы лучше, если бы вы привыкли к strncpy() вместо этого.

strdup() - это, примерно, комбинация strlen() + malloc() + strcpy() и, как правило, наиболее простой вариант, когда вы хотите получить копию строки в областях динамической памяти, чтобы впоследствии ее можно было освободить с помощью free().

РЕДАКТИРОВАТЬ 2:

В приведенном выше коде вы используете буфер sub только для ответных сообщений, а затем освобождаете его.Если это будет последним поведением вашего кода, вы можете просто удалить вызовы malloc() и free(), и это, вероятно, будет хорошо.

2 голосов
/ 08 декабря 2010

Для меня это звучит как повреждение кучи - вы пытались запустить вашу программу без /* -- Some Code -- */?

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

Обновление: Глядя на вашу вторую публикацию кода, на самом деле может оказаться, что вы непреднамеренно изменили значение указателя sub (он же повреждение стека)возможно, написав за конец buf.Это почти наверняка приведет к сбою free.

Проверьте значение sub сразу после вызова malloc, а затем еще раз непосредственно перед free, чтобы убедиться, что оно не изменилось.

Обновление 2: Поцарапайте - thkala Имеет правильный ответ.

0 голосов
/ 08 декабря 2010

Потому что 'sub' потерял ссылку, которая является адресом результата malloc (). Сначала sub указывает начальный адрес результата функции malloc (). когда вы, однако, разрешаете 'sub' 'Правильное написание', 'sub' не указывает память, выделенную malloc (). это стало начальным адресом этой строки - "Corr--" -. Если вы используете 'sub', чтобы попытаться освободить память, malloc (), компилятор отправит вам ошибку, потому что 'sub' не указывает на адрес malloc (), а также вы не можете освободить строку (char arrary) .

вы не пропустите, что sub является одним из значений указателя, а не самой памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...