s [-1] = 0是什么意思?

时间:2014-01-24 20:20:06

标签: c libc

当我在我的机器上运行时,我正在研究bsd的libc函数strtok的代码, 该程序在SIGSEGV中收到了信号s[-1] = 0。 这是代码的link

s[-1] = 0是对吗?

这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include "strtok.c"

int main(int argc, char* argv[]) {
    char* str = "xxxx xxxyy fdffd";
    const char* s = " ";

    char* token = strtok(str, s);

    while (token != NULL) {
        printf("%s\n", token);
        token = strtok(NULL, s);
    }

    return 0;
}

6 个答案:

答案 0 :(得分:6)

s[-1]

扩展为:

*( s - 1 )

因此,如果结果指向有效内存,则定义代码。

答案 1 :(得分:3)

这是可以的,因为s是我们可以从草案C99标准中看到的指针E1[E2] is identical to (*((E1)+(E2)))来自6.5.2.1 部分订阅部分(强调我的):

  

后缀表达式后跟方括号[]中的表达式是下标   指定数组对象的元素。下标运算符[]的定义   是 E1 [E2]与(*((E1)+(E2)))相同。由于转换规则   应用于二进制+运算符,如果E1是一个数组对象(等效地,指向   数组对象的初始元素),E2是整数,E1 [E2]表示E2   E1的元素(从零开始计数)。

如果s是一个数组,那么这将不是有效的代码,因为我们将访问不属于数组的内存,这将是未定义的行为。

答案 2 :(得分:3)

s[-1]指的是s指向的对象前面

根据C的规则,s[-1]相当于*(s-1)。这样:

  • 计算s-1。结果是s指向的对象之前指向对象的指针,与s+1之后指向对象的指针的方式相同。
  • Defere it,它为指向对象生成左值。

因此,ss[-1] = 0指向的对象之前为对象指定0。

s是合法代码,如果s[-1]指向第一个元素后面的数组元素(从而确保在它之前有一个元素)或s指向一个元素之外的元素数组的结尾。 (如果s指出一个超出不在数组中的单个对象,这也是合法的,这是一种不寻常的用途。)

答案 3 :(得分:1)

应该没问题,因为它上面几行就是s ++,所以最糟糕的情况我们正在使用(s + 1)-1。

答案 4 :(得分:1)

s[-1] = 0是“正确”还是“错误”取决于s的运行时值。

s[-1] = 0本身没有任何内在错误或不寻常的错误。

答案 5 :(得分:0)

只是预感,但我相当确定FreeBSD的strtok(3)非常稳定且经过充分测试。

schar*; s[-1]s指向的字符设置为NUL

我们可以看到您调用strtok(3)的实际代码吗?可以这么说,问题可能在你的设置中。此外,您是否阅读了手册页?

  

第一次调用strtok()时,应指定str;   后续调用,希望从同一串中获取更多令牌,   应该传递一个空指针。分隔符字符串sep,   必须每次都提供,并且可以在不同呼叫之间改变。