C语言 客户端代码中发生分段错误

fruv7luv  于 2023-05-16  发布在  其他
关注(0)|答案(1)|浏览(98)

我不太擅长编程,我正在经历一个非常令人沮丧的时刻,我正在编写一个客户端和服务器的东西,在我的客户端代码中,有一些东西导致了分割错误,我不知道是什么:

uint16_t recevoir_liste_comptines(int fd)
{
    char buf[BUF_SIZE];
    char** comptines = NULL;
    uint16_t comptine_count = 0;
    int i;
    ssize_t n = read(fd, buf, 256);
    if (n < 0) {
        perror("read");
        exit(EXIT_FAILURE);
    }

    char *token=malloc(128*sizeof(char));
    if (token==NULL)
    {
        perror("malloc ici");
        exit(EXIT_SUCCESS);
    }
    token= strtok(buf, "\n");
    while (token != NULL && comptine_count < MAX_COMPTINES) {
        comptines = realloc(comptines, (comptine_count + 1) * sizeof(char*));
        if (comptines == NULL) {
            perror("realloc");
            exit(EXIT_FAILURE);
        }
        comptines[comptine_count++] = strdup(token);
        token = strtok(NULL, "\n");
    } 

    // Affiche les comptines à partir du tableau
    for (i = 0; i <= comptine_count; i++) {
        printf("%s\n",  comptines[i]);
        free(comptines[i]);
    }
    free(comptines);
    free(token);
    return comptine_count;
}

context:这个函数必须接收一个包含标题列表的缓冲区并显示它们,所有这些都返回标题的数量。我花了几个小时试图找出问题,但我不知道它是什么,我相信问题来自这个函数,有时(罕见的时刻)它工作得很好,没有错误,但大多数错误是存在的。我很乐意在这里找到帮助,谢谢!

bjp0bcyl

bjp0bcyl1#

1,你提供了一个片段,所以我用它构建了一个最小的程序,它在该行上segfaults:

printf("%s\n",  comptines[i]);

实际上,作为@pmacfarlane,这是因为循环条件和应该是:

for (i = 0; i < comptine_count; i++) {

1.不为token分配空间。当它被strtok()`的结果覆盖时,它随后泄漏:

char *token=malloc(128*sizeof(char));
    if (token==NULL)
    {
        perror("malloc ici");
        exit(EXIT_SUCCESS);
    }

1.不要使用free(token),因为它指向buf(在某个偏移量处),这是一个堆栈分配的变量。@pmacfarlane也指出了这一点。
1.对realloc()使用临时变量,否则在realloc()失败时会泄漏comptines。因此,而不是:

comptines = realloc(comptines, (comptine_count + 1) * sizeof(char*));

你想做的事:

char **tmp = realloc(comptines, (comptine_count + 1) * sizeof(char*));
if(!tmp) {
   // ...
}
comptines = tmp;

1.最小化变量的作用域。在原始程序中,将int i设为局部循环变量。comptine_count移动到使用前。
1.程序的唯一效果是打印每个标记并对其进行计数,因此没有必要将字符串存储在comptines中。
下面是我最终得到的相应程序:

#define _POSIX_C_SOURCE 200809L
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>

#define BUF_SIZE 42
#define MAX_COMPTINES 10

uint16_t f(int fd) {
    char buf[BUF_SIZE];
    ssize_t n = read(fd, buf, 256);
    if (n < 0) {
        perror("read");
        exit(EXIT_FAILURE);
    }

    uint16_t comptine_count = 0;
    for(; comptine_count < MAX_COMPTINES; comptine_count++) {
        char *token = strtok(comptine_count ? NULL : buf, "\n");
        if(!token)
            break;
        printf("%s\n",  token);
    }

    return comptine_count;
}

int main() {
    int fd = open("input.txt", O_RDONLY);
    if(fd == -1) {
        perror("open");
        exit(EXIT_FAILURE);
    }
    printf("%hu\n", f(fd));
    close(fd);
}

相关问题