简体   繁体   English

在pthread_create中指定的函数中释放参数

[英]freeing argument in function specified in pthread_create

I am writing a small server which creates a new thread to handle each new connection. 我正在编写一个小型服务器,该服务器创建一个新线程来处理每个新连接。 I need to pass the socket to the function using the fourth argument of pthread_create. 我需要使用pthread_create的第四个参数将套接字传递给函数。 When trying to free the memory used for the socket i get a segfault. 当试图释放用于套接字的内存时,出现了段错误。 The communication works fine. 通讯正常。 I have tried passing a void* and also a void** (casted to void*, kind of ugly) 我尝试传递一个void *和一个void **(投射到void *,有点丑陋)

This is the latest cludge i'm using while trying to figure this out, later if will be doing actual work in the respond function. 这是我试图弄清楚这一点时最新使用的方法,以后再在响应函数中进行实际工作时。

#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);
}

Lastly, to clarify; 最后,要澄清; I am very inexperienced when it comes to c. 我对c经验不足。 :) :)

You have a massive memory leak and general memory error: 您有大量的内存泄漏和一般的内存错误:

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

The first line allocates memory and assigns the pointer to cs , and the second line immediately throws away that pointer by overwriting it with the integral value client_sock . 第一行分配内存并将指针分配给cs ,第二行通过使用整数值client_sock覆盖该指针,立即丢弃该指针。 Later you try to free that value, which is a flagrant error, since it's not a valid pointer. 稍后,您尝试释放值,这是一个公然的错误,因为它不是有效的指针。

You should structure your code like this: 您应该像这样构建代码:

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

And the thread function: 和线程功能:

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

There's no need for the extra indirection by taking the address of cs . 不需要通过使用cs的地址进行额外的间接cs

Don't allocate a pointer. 不要分配指针。 Pass the socket file descriptor directly to pthread_create() : 将套接字文件描述符直接传递给pthread_create()

(void*)client_sock

Then, in respond() : 然后,在respond()

client_sock = (int)thread_arg;

No malloc() or free() necessary. 不需要malloc()free()

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

The second assignment makes you have a memory leak in your code. 第二项分配使您的代码中发生内存泄漏。

try something more like this. 尝试更多类似的东西。

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

Then you don't need this casting. 然后,您不需要这种转换。

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

and you can just free the thread_arg. 您就可以释放thread_arg了。

free(thread_arg);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM