s = 0是什么意思?

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

s[-1] = 0对吗?

这是我的代码:

 #include  #include  #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; } 

 s[-1] 

扩大到:

 *( s - 1 ) 

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

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

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

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

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

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

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

因此, s[-1] = 0在指向的对象之前将s[-1] = 0赋给对象。

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

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

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

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

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

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

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

第一次调用strtok() ,应该指定str ; 后续调用希望从相同的字符串中获取更多标记,而应该传递空指针。 必须每次都提供分隔符字符串sep ,并且可以在调用之间进行更改。