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)
非常稳定且经过良好测试。
s
是char*
; s[-1]
将s
指向的前面的字符设置为NUL
。
我们能看到你正在调用strtok(3)
实际代码吗? 可以这么说,问题可能在你的设置中。 此外,您是否阅读了手册页?
第一次调用
strtok()
,应该指定str
; 后续调用希望从相同的字符串中获取更多标记,而应该传递空指针。 必须每次都提供分隔符字符串sep
,并且可以在调用之间进行更改。