LInux 中的 C 套接字编程,双重释放损坏 (fasttop) 错误

标签 c linux sockets free corruption

我已经阅读了其他类似问题的答案,但似乎没有一个能解决我的问题。

这是我的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <pthread.h>

typedef struct {
  pthread_t thread_id;
  int sockfd;
} client_t;

client_t *clients;
size_t client_n = 0;

void *client_thread(void *client_ptr) {
  client_t client = *(client_t*) client_ptr;
  char buffer[500];
  int state;
  while(1) {
    state = send(client.sockfd, 0, 1, MSG_NOSIGNAL);

    if(state == -1) {
      printf("socket-%d closed\n", client.sockfd);
      break;
    }

    read(client.sockfd, buffer, 500);
    printf("from socket-%d: %s\n", client.sockfd, buffer);
    memset(buffer, 0, 500);
  }
  close(client.sockfd);
  free(client_ptr);
  client_n--;
}

int main(int argc, char *argv[]) {
  int sockfd, newsockfd, clilen;
  struct sockaddr_in clientaddr, serveraddr;

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  serveraddr.sin_family = AF_INET;
  serveraddr.sin_addr.s_addr = INADDR_ANY;
  serveraddr.sin_port = htons(8080);

  bind(sockfd, (struct sockaddr*) &serveraddr, sizeof(serveraddr));
  listen(sockfd, 5);

  clilen = sizeof(clientaddr);

  clients = (client_t*) malloc(sizeof(client_t));

  while(1) {
    newsockfd = accept(sockfd, (struct sockaddr*) &clientaddr, &clilen);
    printf("New connection: socket-%d\n", newsockfd);
    clients = (client_t*) realloc(clients, (client_n + 1) * sizeof(client_t));
    clients[client_n].sockfd = newsockfd;
    pthread_create(&clients[client_n].thread_id, NULL, client_thread, (void*) &clients[client_n]);
    client_n++;
  }
  return 0;
}

程序应该监听传入的连接,然后为每个连接创建一个新线程。然后该程序将同时处理每个客户端。由于这应该是游戏服务器的核心,因此我创建了一个结构来包含每个玩家的信息。

一切正常,直到我添加:

close(client.sockfd);
  free(client_ptr);
  client_n--;

知道问题出在哪里吗?

最佳答案

free(client_ptr);
client_n--;

两个问题。

第一个是免费通话。您实际上并未为 client_ptr 调用 malloc(或 realloccalloc)。相反,client_ptr 指向您动态分配的数组,但 client_ptr 指向的元素本身并不是单独动态分配的。当您传递一个指向 free 的指针时,这会导致未定义的行为,而该指针实际上并未使用 malloc 和系列进行分配。 除了第一个元素(即clients[0]),当您释放整个数组时。解决这个问题的方法就是不在线程中调用free

另一个问题是 client_n-- 表达式。您不保护此(或 main 函数中相应的 client_n++)免受其他线程的修改。这意味着两个或多个线程可能会同时修改此值,从而再次导致未定义的行为。您需要有一个信号量或互斥体来保护此修改。

<小时/>

还有一些其他问题。例如,您不加入已结束的线程,从而导致资源泄漏。您不会通过 read 调用检查错误或已关闭的连接(返回 0read 调用会报告良好关闭的连接)。

关于LInux 中的 C 套接字编程,双重释放损坏 (fasttop) 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45388463/

相关文章:

c - 用于发送和接收的单套接字多端口或多套接字多端口

javascript - 如何让用户通过在 url 中输入房间名称来进入特定房间?套接字.io

c - 找出多组数字之间的最大差异

c - 数据类型char的存储

c - 返回数组的函数

python - 当 python 请求结束时切换到服务器上的另一个 IP

linux - 如何在 linux 中最后一次出现特定命令之前运行所有命令

c++ - 无法在 Linux Mint 中运行简单的 OpenGL 程序

C 在文本文件中隔离 "only strings"

c - 从结构体发送数据,套接字编程