C-标记文件中的行时发生总线错误
我正在写一个C程序来读取和标记文件中的行。然而,我在编译时遇到了一个总线错误,在进行了大量调试之后,它让我感到困惑 这些文件有三个数字(1-2位),用空格分隔,末尾还有一个可选的星号。因此:C-标记文件中的行时发生总线错误,c,C,我正在写一个C程序来读取和标记文件中的行。然而,我在编译时遇到了一个总线错误,在进行了大量调试之后,它让我感到困惑 这些文件有三个数字(1-2位),用空格分隔,末尾还有一个可选的星号。因此: 1 2 4 8 16 32 * 64 1 1 * 这是通过以下方式分析的: #define BUFFER_SIZE 12 #define MAX_PARTS 4 #define MAX_DIGITS 2 int parse(FILE *file) { char line[BUFFER_SIZE]
1 2 4
8 16 32 *
64 1 1 *
这是通过以下方式分析的:
#define BUFFER_SIZE 12
#define MAX_PARTS 4
#define MAX_DIGITS 2
int parse(FILE *file)
{
char line[BUFFER_SIZE];
while (fgets(line, BUFFER_SIZE, file)) {
char **tokens = tokenize(line);
printf("[%s][%s][%s][%s]\n",
tokens[0],
tokens[1],
tokens[2],
tokens[3]);
// Free...
}
// Close file, return...
}
虽然我不认为我的腋窝**tokenize()
函数是问题所在,但它仍然存在:
char **tokenize(char line[])
{
char **tokens = (char **)malloc(MAX_PARTS * sizeof(char *));
char *token = strtok(line, " ");
unsigned int n_tokens = 0;
while (token != NULL && n_tokens < 4) {
tokens[n_tokens] = (char *)malloc(MAX_DIGITS + 1 * sizeof(char));
strncpy(tokens[n_tokens], token, MAX_DIGITS + 1);
token = strtok(NULL, " ");
n_tokens++;
}
return tokens;
}
char**tokenize(字符行[])
{
char**tokens=(char**)malloc(MAX_PARTS*sizeof(char*);
char*token=strtok(行“”);
无符号整数n_标记=0;
while(令牌!=NULL&&n_令牌<4){
令牌[n_令牌]=(字符*)malloc(最大数字+1*sizeof(字符));
strncpy(令牌[n_令牌]、令牌、最大\u位数+1);
令牌=strtok(空,“”);
n_代币++;
}
归还代币;
}
parse()
将断开的字符数组传递给tokenize()
似乎有问题,但我不确定。对C的复杂性仍然陌生:-)
提前谢谢
运行
gcc*.c-g-fsanize=leak-fsanize=address
并运行时
如果使用/a.out[必要标志]
,控制台将返回总线错误(core
倾倒)
如果您的文件有时可能包含仅由3部分组成的行,则
标记
-数组的最后一个条目保持未初始化状态。如果随后访问它,例如在printf(“[%s][%s][%s][%s][%s]\n]”,…
,则调用未定义的行为,通常会导致类似“分段错误”或其他情况
所以我要做两件事:
首先,确保您的tokens
数组初始化为空(即NULL)。这可以通过calloc
而不是malloc
轻松实现,例如char**tokens=malloc(MAX_PARTS,sizeof(char*))
其次,确保不打印NULL
-指针。例如,为(char*s=tokens;s;s++)printf(“%s\n”,s)编写一个类似的循环
顺便说一句:重新考虑是否确实有必要为每行的令牌分别分配内存。可能您传递了一个“pre-malloced”数组进行标记化,然后一次又一次地填充。注意,在这种情况下,您必须在每次调用之前清除数组。如果您的文件有时可能包含仅由3部分组成的行,则您的标记的最后一个条目将保持未初始化状态。如果您随后访问它,例如在printf(“[%s][%s][%s][%s]\n“,…
,然后调用未定义的行为,通常会导致类似“分段错误”或其他情况
所以我要做两件事:
首先,确保您的tokens
数组初始化为空(即NULL)。这可以通过calloc
而不是malloc
轻松实现,例如char**tokens=malloc(MAX_PARTS,sizeof(char*))
其次,确保不打印NULL
-指针。例如,为(char*s=tokens;s;s++)printf(“%s\n”,s)
编写一个类似的循环
顺便说一句:重新考虑是否确实有必要为每行的令牌分别分配内存。可能您传递了一个“pre-malloced”数组进行标记化,然后一次又一次地填充。注意,在这种情况下,每次调用之前都必须清除数组。您能描述一下总线错误是什么吗?运行gcc*.c-g-fsanize=leak-fsanize=address
并使用/a.out[必要标志]运行时
,控制台返回总线错误(内核转储)
。令牌[3]
在读取第一行后保留了什么?您打印了它,但没有读取令牌。令牌[3]
未初始化。哇!我在printf()中添加了
为了便于说明,但即使没有它,我仍然会得到一个总线错误。叹气。请发布显示问题的。您能为您描述一下什么是总线错误吗?当运行gcc*.c-g-fsanize=leak-fsanize=address
并使用/a.out[必要标志]
运行它时,控制台返回总线错误(内核转储)
。读取第一行后,tokens[3]
保留什么?您打印了它,但没有读取令牌。tokens[3]
未初始化。哎哟。我在printf()中添加了
用于说明目的,但即使没有它,我仍然会收到一个总线错误。叹气。请发布显示问题的。解决了我的问题并提出了一个好建议。谢谢Stephan!解决了我的问题并提出了一个好建议。谢谢Stephan!