我不太擅长编程,我正在经历一个非常令人沮丧的时刻,我正在编写客户端和服务器的代码,在我的客户端代码中,有一些东西导致了分段错误,我不知道是什么它是:
{
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:这个函数必须接收一个包含标题列表的缓冲区并显示它们,所有这些都返回标题的数量。我花了几个小时试图找出问题所在,但我不知道它是什么,而且我确信问题出在这个函数上,有时(很少见)它工作得很好,没有错误,但主要是错误有没有。我很乐意在这里找到帮助,谢谢!
1,你只提供了一个片段,但我构建了一个程序然后它在线上出现段错误:
printf("%s\n", comptines[i]);
确实是@pmacfarlane,这是因为循环条件应该是:
for (i = 0; i < comptine_count; i++) {
char *token=malloc(128*sizeof(char));
if (token==NULL)
{
perror("malloc ici");
exit(EXIT_SUCCESS);
}
不要
free(token)
,因为它指向buf
(在某个偏移处)并且它是一个堆栈分配变量。 @pmacfarlane 也指出了这一点。
将临时变量与
realloc()
一起使用,否则会在失败时泄漏内存。所以代替:
comptines = realloc(comptines, (comptine_count + 1) * sizeof(char*));
你想做的事:
char **tmp = realloc(comptines, (comptine_count + 1) * sizeof(char*));
if(!tmp) {
// ...
}
comptines = tmp;
最小化变量的范围。在您的原始程序中,使
int i
成为局部循环变量。 comptine_count
移至即将使用前。
你的程序唯一的作用是打印每个标记来计算它们,所以没有必要将字符串存储在
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);
}