strtok_r导致分段错误

时间:2018-02-09 14:31:45

标签: c++ segmentation-fault

此代码用于解析csv文件,但会导致分段错误。 我可以在这里看到类似的代码:Nested strtok function problem in C

它们看起来相同,但我的代码会导致分段错误。为什么呢?

setRetainInstance(true)

3 个答案:

答案 0 :(得分:2)

Jean-Francois是对的。只需在调用atoi之前检查该值,如下所示。每次打电话atoi

时都需要这样做
if(data_point_attr != NULL)
    user = atoi(data_point_attr);

答案 1 :(得分:2)

您的内循环不需要且对您的程序有毒。

内循环提取3个标记,然后继续,提取第4个标记但在中间到达NULLatoi传递NULL:segfault。

你只需要一个循环(为了理智而添加assert语句):

    while(data_point != NULL) {
        char *end_attr;
        char *data_point_attr = strtok_r(data_point, ",", &end_attr);

            user = atoi(data_point_attr);
            data_point_attr = strtok_r(NULL, ",", &end_attr);
            assert(data_point_attr != NULL);
            item = atoi(data_point_attr);
            data_point_attr = strtok_r(NULL, ",", &end_attr);
            assert(data_point_attr != NULL);
            rating = atoi(data_point_attr);
            strtok_r(NULL, ",", &end_attr);
            input.push_back({user, item, rating});
            maxUser = max(maxUser, user);
            maxItem = max(maxItem, item);

        data_point = strtok_r(NULL, ";", &end_str);
    }

更好的解决方案是使用真正的C ++解决方案来分割字符串。

答案 2 :(得分:2)

根据Valgrind的说法,你的计划在这里失败了:

                item = atoi(data_point_attr);

,因为函数参数为NULL。这似乎与让 - 弗朗索瓦的预测一致。使用gdb进行一些调试表明它发生在第二次循环迭代中,尽管你甚至可以通过print-statement调试确定它。而对gdb进行更多调试会显示正在发生的事情:您的内部循环有问题,因为当您到达记录末尾时,循环条件不会变为false。

无论如何,你还需要那个内循环?没有。您正在通过单独的语句读取每个值,因此您已经有效地展开了循环 vs。在程序中需要使用任意 CSV的内容。 执行检查每个strtok_r()调用的结果,但删除不需要的内部循环。