例如,如果我有一个字符串的ptr并将ptr移动到字符串中的最后一个字符并使用* p--向后迭代到字符串的开头,并且我在数组开始之前迭代到位置1这样可以吗?或者我会获得访问冲突?我只是移动指针 - 不访问。它似乎在我的代码中工作,所以想知道它是不是很糟糕的做法?
这是一个样本行,其中* next-- = rem +'A';是一个我在质疑,如果好吗???
#include <stdio.h> /* printf */
#include <string.h> /* strlen, strcpy */
#include <stdlib.h> /* malloc/free */
#include <math.h> /* pow */
/* AAAAA (or whatever length) = 0, to ZZZZZ. base 26 numbering system */
static void getNextString(const char* prev, char* next) {
int count = 0;
char tmpch = 0;
int length = strlen(prev);
int i = 0;
while((tmpch = *prev++) != 0) {
count += (tmpch - 'A') * (int)pow(26.0, length - i - 1);
++i;
}
/* assume all strings are uppercase eg AAAAA */
++count;
/*if count above ZZZ... then reset to AAA... */
if( count >= (int)pow(26.0, length))
count = 0;
next += (length-1); /* seek to last char in string */
while(i-- > 0) {
int rem = count % 26;
count /= 26;
*next-- = rem + 'A'; /*pntr positioned on 1 before array on last iteration - is OK? */
}
}
int main(int argc, char* argv[])
{
int buffsize = 5;
char* buff = (char*)malloc(buffsize+1);
strcpy(buff, "AAAAA");
int iterations = 100;
while(--iterations){
getNextString(buff, buff);
printf("iteration: %d buffer: %s\n", iterations, buff);
}
free(buff);
return 0;
}
答案 0 :(得分:7)
根据以下C-FAQ question\answer,我引用:
只要指针指向,就会定义指针运算 在相同分配的内存块内,或虚构内 “终止”元素一个过去;否则,行为是 undefined,即使指针没有被解除引用。
所以我的答案是没有,在数组开始之前迭代是不行的。
也有对C标准的引用:
答案 1 :(得分:1)
只要您不尝试从该地址读取或写入,就不会导致违规。这是因为ptr中的值只是另一个数字。
答案 2 :(得分:0)
您的代码工作的唯一原因是您的长度恰好小于或等于i中的初始值。
我个人不想依赖于此,因为我知道我会忘记这个特殊情况,而且我会做一些修改而破坏它。因此,虽然它在技术上有效,但它并不是一个好主意。
答案 3 :(得分:0)
[expr.add],¶5
如果指针操作数和结果都指向同一个数组对象的元素,或者一个过去的元素 数组对象的最后一个元素,评估不应产生溢出;否则,行为是 未定义。
所以它是UB,因为结果不指向数组的任何有效元素。
答案 4 :(得分:0)
评论,实际上:(对FelixCQ的回答)
我可以理解为什么在循环中获得超出范围的指针可能是危险的,因为可能的循环展开和无序评估,因此在评估终止条件之前指针可以被解除引用,如这个简单的例子:
for (char* tmp = s+len; tmp >= s; tmp--) sum += *tmp;
但是,如果这是UB的原因,那么
for (int i = len; i >= 0; i--) sum += s[i];
有完全相同的问题!或者我错过了什么?