从超出数组的指针指向数组访问是否安全?

时间:2019-06-27 15:17:24

标签: c

道歉的问题措辞道歉,但归结为这一点。我正在维护执行以下操作的C代码:

char *foo = "hello"
int i;
char *bar;

i = strlen(foo);
bar = &foo[i];

这样安全吗?可能会发生foo[i]导致分段错误,而该错误在获得指针之前被编译器所覆盖吗?

2 个答案:

答案 0 :(得分:5)

是的,您可以在数组末尾设置一个指针(尽管您实际上并没有在代码中这样做,而是指向NUL终止符)。

请注意,尽管解引用指针的行为设置为数组末尾的指针将是不确定的。

(请注意,C标准要求对&foo[i]进行评估时必须不取消引用指针:即&foo[i + 1]是有效的,但是foo[i + 1]本身不是。)

答案 1 :(得分:1)

  

我正在维护执行以下操作的C代码:

char *foo = "hello"
int i;
char *bar;

i = strlen(foo);
bar = &foo[i];
     

这样安全吗?

所提供的代码符合当前和所有过去的C语言标准,并且每种标准都有相同的明确定义的行为。特别要注意,就像所有其他C字符串一样,C字符串文字表示以空值结尾的字符数组,因此在示例代码中也是如此。 foo[i]指向终止符,&foo[i]指向数组(指向其最后一个元素),而不是指向其外部。

此外,C还允许获得指向数组末尾的指针,因此,即使1 + &foo[i]也是有效且符合标准的。不允许取消引用此类指针,但是您可以执行指针算术运算并对其进行比较(受常规约束)。

  

在某些情况下foo [i]会导致   分段错误,在获得指针之前,并没有被   编译器?

C对于分段错误无话可说。每当您收到一个消息时,要么您的实现显示不合格,要么(几乎总是)您的程序正在执行未定义的行为。所提供的代码符合strlen()的正确声明,并且在其范围内,并且如果它出现在符合该要求的完整程序中并且没有以其他方式使用UB,则没有理由出于普遍怀疑而担心段错误。