我的客户端代码发生分段错误

问题描述 投票:0回答:1

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

{
    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:这个函数必须接收一个包含标题列表的缓冲区并显示它们,所有这些都返回标题的数量。我花了几个小时试图找出问题所在,但我不知道它是什么,而且我确信问题出在这个函数上,有时(很少见)它工作得很好,没有错误,但主要是错误有没有。我很乐意在这里找到帮助,谢谢!

c server memory-leaks segmentation-fault client
1个回答
1
投票

1,你只提供了一个片段,但我构建了一个程序然后它在线上出现段错误:

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

确实是@pmacfarlane,这是因为循环条件应该是:

for (i = 0; i < comptine_count; i++) {
  1. 不要为令牌分配空间(因为它随后会泄漏内存):
    char *token=malloc(128*sizeof(char));
    if (token==NULL)
    {
        perror("malloc ici");
        exit(EXIT_SUCCESS);
    }
  1. 不要

    free(token)
    ,因为它指向
    buf
    (在某个偏移处)并且它是一个堆栈分配变量。 @pmacfarlane 也指出了这一点。

  2. 将临时变量与

    realloc()
    一起使用,否则会在失败时泄漏内存。所以代替:

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
    移至即将使用前。

  2. 你的程序唯一的作用是打印每个标记来计算它们,所以没有必要将字符串存储在

    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);
}
© www.soinside.com 2019 - 2024. All rights reserved.