简体   繁体   中英

segfault when using strtok_r

i want to split a string in c with this code:

char *search = "+" ;
char *temp1;
char *temp2;
char *saveptr1, *saveptr2 ;
int operand1 ;
int operand2 ;
int result ;
char sumBuff [5][25]    
temp1 = strtok_r(sumBuff[sumCounter-1], search, &saveptr1) ;
operand2 = atoi(strtok_r(NULL, search, &saveptr1));
temp2 = strtok_r(temp1, ".", &saveptr2) ;
operand1 = atoi(strtok_r(NULL, ".", &saveptr2)) ;

but when i run this in my main code i get the segmentation fault. and this is the trace stack result:

#0  0x00007ffff7834517 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff7830f60 in atoi () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x000000000040108c in plusExec (arg=0x0) at cm.c:112
#3  0x00007ffff7bc4182 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0
#4  0x00007ffff78f147d in clone () from /lib/x86_64-linux-gnu/libc.so.6

cm.112 is operand2 = atoi(...) How can i correct this error?

You do not check for the return of strtok_r , which can be NULL and therefore crash atoi .

And in this case:

temp2 = strtok_r(temp1, ".", &saveptr2) ;
operand1 = atoi(strtok_r(NULL, ".", &saveptr2)) ;

...you seem to be looking for two consecutive points ? Such as 5.123.723? If there is only one, atoi will receive NULL and coredump.

If there shouldn't be two consecutive "."'s, then that's likely to be a bug.

Supposing it is not , try:

temp2 = strtok_r(temp1, ".", &saveptr2); // E.g. 5

// If there is no other token, operand1 is set to zero.
operand1 = 0;
if (temp2 != NULL) {
    char *temp3;
    temp3 = strtok_r(NULL, ".", &saveptr2); // E.g. 123, or NULL
    if (temp3 != NULL) {
        operand1 = atoi(temp3);
    }
}

(Same approach for the first atoi ).

Depending on the data format, you might perhaps employ a parser function that would return an array of integers and its cardinality; again, if you need to deal with variably-dotted quantities , such as 192.168.1.1 or 1.2.7.0.80.17 - otherwise you needn't bother:

/**
 * Parses a string in the format 1.2343.293.777
 * @param char * inputString       Input string
 * @param int * vect               Vector where to store integers
 * @param size_t n                 Maximum vector size
 * @return size_t                  Number of integers returned
 */

size_t parseDottedIntegers(char *inputString, int *vect, size_t n) {
    size_t i = 0;
    char *p;
    char *save = NULL;
    p = strtok_r(inputString, ".", &save);
    while (i < n) {
        vect[i++] = atoi(p);
        p = strtok_r(NULL, ".", &save);
        if (NULL == p) {
            return i;
        }
    }
    // Error (e.g. too many parts)
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM