使用strtok_r时出现段错误

时间:2015-06-18 20:58:27

标签: c segmentation-fault

我想用以下代码在c中拆分字符串:

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)) ;

但是当我在我的主代码中运行它时,我得到了分段错误。 这是跟踪堆栈结果:

#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.112operand2 = atoi(...) 我该如何纠正这个错误?

1 个答案:

答案 0 :(得分:2)

您不会检查strtok_r的返回值,该值可能为NULL,因此会导致atoi崩溃。

在这种情况下:

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

......你似乎在寻找连续两个分?如5.123.723?如果只有一个,atoi将收到NULL和coredump。

如果不应该有两个连续的“。”,则可能是一个错误。

假设,请尝试:

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);
    }
}

(第一个atoi的方法相同)。

根据数据格式,您可能会使用解析器函数来返回整数数组及其基数;再次,如果您需要处理可变点数量,例如192.168.1.1或1.2.7.0.80.17 - 否则您无需费心:

/**
 * 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;
}