Q:

strtok_r results in segmentation fault

This code is to parse a csv file, but it results in segmentation fault. 
I could see the similar code here: Nested strtok function problem in C
They look same but my code results in segmentation fault.  Why? 
#include <cstdlib>
#include <string.h>
#include <stdio.h>
#include <vector>

using namespace std;

struct inputTuple{
    int user, item, rating;
};

int main(void)
{
    char xdata[] = "1,88,0,874965758;1,2,1,876893171;1,99,1,878542960;";
    vector<inputTuple> input;

            int maxUser = 0, maxItem = 0;
        int user, item, rating;

        char *end_str;
        char *data_point = strtok_r(xdata, ";", &end_str);

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

                user = atoi(data_point_attr);
                data_point_attr = strtok_r(NULL, ",", &end_attr);
                item = atoi(data_point_attr);
                data_point_attr = strtok_r(NULL, ",", &end_attr);
                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);
        }
    return 0;
}

A:

your inner loop is not needed AND toxic to your program. 
The inner loop extracts 3 tokens, then continues, extract the 4th token but reaches NULL in the middle, and atoi is passed NULL: segfault. 
You only need one loop (added assert statements for sanity though):
    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);
    }

A better solution would be to use a real C++ solution to split the strings.