освобождение аргумента в функции, указанной в pthread_create - PullRequest
2 голосов
/ 04 января 2012

Я пишу небольшой сервер, который создает новый поток для обработки каждого нового соединения.Мне нужно передать сокет функции, используя четвертый аргумент pthread_create.При попытке освободить память, используемую для сокета, у меня возникает ошибка.Связь работает нормально.Я попытался передать пустоту *, а также пустоту ** (приведено к пустоте *, что-то уродливое)

Это последний клуд, который я использую, пытаясь выяснить это, позже, если буду делатьфактическая работа в функции ответа.

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <pthread.h>

void *respond(void *thread_arg)
{
        void *arg = *(void**)thread_arg;
        printf("responding...\n");
        int client_sock;
        client_sock = (int)arg;

        char *message = "Write smthng to echo!\n\t";
        send(client_sock,message,strlen(message),0);
        char *buf = (char*)malloc(100);
        int ptr = 0;
        char last = ' ';
        while (last != '\n') {
                recv(client_sock,&last,1,0);
                buf[ptr++] = last;
        }
        buf[ptr++] = '\n';
        send(client_sock, buf, ptr, 0);
        ptr = 0;
        free(buf);
        close(client_sock);
        //free(arg); // why segfault?
        //free(*(void**)thread_arg); // the same
        pthread_exit(NULL);
}

int main(int argc, char **argv)
{
        int socket_desc, client_sock, addrlen, tmp;
        struct sockaddr_in address;
        pthread_t *responder_thread;
        void *cs;

        socket_desc = socket(AF_INET, SOCK_STREAM, 0);
        if (socket_desc < 0)
                printf("could not create socket");
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        address.sin_port = htons(8080);
        tmp = bind(socket_desc, (struct sockaddr *)&address, sizeof(address));
        if (tmp < 0)
                printf("could nod bind to port!");
        listen(socket_desc, 5);

        addrlen = sizeof(struct sockaddr_in);
        while (true) {
                client_sock = accept(socket_desc, (struct sockaddr *)&address, (socklen_t*)&addrlen);
                if (client_sock < 0) {
                        printf("could not create client socket");
                } else {
                        printf("Accepted connection!\n");
                        cs = malloc(sizeof(int));
                        cs = (void*)client_sock;
                        responder_thread = (pthread_t*)malloc(sizeof(pthread_t*));
                        tmp = pthread_create(responder_thread, NULL, respond, (void*)&cs);
                        //cs = NULL;
                        if (tmp) {
                                printf("pthread_create returned '%d', exiting", tmp);
                                exit(-1);
                        }

                }
        }
        pthread_exit(NULL);
}

Наконец, чтобы уточнить;Я очень неопытен, когда дело доходит до c.:)

Ответы [ 4 ]

3 голосов
/ 04 января 2012

У вас серьезная утечка памяти и общая ошибка памяти:

cs = malloc(sizeof(int));
cs = (void*)client_sock;

Первая строка выделяет память и назначает указатель на cs, а вторая строка немедленно выбрасывает этот указатель, перезаписывая егоинтегральное значение client_sock.Позже вы попытаетесь освободить это значение , что является вопиющей ошибкой, поскольку это недопустимый указатель.

Вы должны структурировать свой код следующим образом:

int * cs = malloc(sizeof(int));
*cs = client_sock;
pthread_create(..., cs);

И функция потока:

void * respond(void * thread_arg)
{
    int * cs = (int*)thread_arg;
    /* ... */
    free(cs);
}

Нет необходимости в дополнительном косвенном обращении, принимая адрес cs.

2 голосов
/ 04 января 2012

Не выделять указатель.Передайте дескриптор файла сокета непосредственно в pthread_create():

(void*)client_sock

Затем в respond():

client_sock = (int)thread_arg;

Нет malloc() или free() обязательно.

1 голос
/ 04 января 2012

попробуйте что-нибудь еще подобное.

int* cs;
...
cs = (int*)malloc(sizeof(int));
*cs = client_sock;
...
tmp = pthread_create(responder_thread, NULL, respond, (void*)cs);

Тогда вам не нужен этот кастинг.

void *arg = *(void**)thread_arg;

и вы можете просто освободить thread_arg.

free(thread_arg);
1 голос
/ 04 января 2012
cs = malloc(sizeof(int));
cs = (void*)client_sock;

Второе назначение вызывает утечку памяти в вашем коде.

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