Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-标记文件中的行时发生总线错误_C - Fatal编程技术网

C-标记文件中的行时发生总线错误

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]

我正在写一个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];

    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!