是否可以向后迭代到数组开头之前的一处
例如,如果我有一个指向字符串的 ptr 并将 ptr 移动到字符串中的最后一个字符,并使用 *p-- 向后迭代到字符串的开头,并且我迭代到在数组开始之前定位一个,这样可以吗?或者我会遇到访问冲突吗?我只是移动指针 - 不访问。它似乎在我的代码中工作,所以想知道这是否是不好的做法?
这是一个示例 - 行 *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;
}
If for example I have a ptr to a string and move ptr to last character in string and iterate backwards to beginning of string using *p-- and I iterate to position one before start of array is this OK? Or will I get an access violation? I am only moving pointer - not accessing. It seems to work in my code so wondering if it is bad practice or not?
Here is a sample - line with *next-- = rem + 'A'; is one I am questioning if ok???
#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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据以下 C-FAQ question\answer,我引用:
所以我的答案是不,在数组开头之前进行迭代是不行的。
还有对 C 标准的引用:
205-6
According to the following C-FAQ question\answer, and I quote:
So my answer would be no, it is not OK to iterate before the beginning of an array.
There are references to the C standards as well:
205-6
只要您不尝试从该地址读取或写入,就不会导致违规。这是因为 ptr 中的值只是另一个数字。
As long as you don't try to read or write from that address, it won't cause a violation. This is becuase the value in a ptr is just another number.
您的代码正常工作的唯一原因是您的长度恰好小于或等于 i 中的初始值。
我个人不想依赖这个,因为我知道我会忘记这个特定的条件,并且我会做出一些修改来破坏它。因此,虽然它在技术上可行,但这并不是一个好主意。
The only reason your code is working is that your length happens to be less than or equal to the initial value in i.
I personally would not want to rely on this, since I know I'd forget about that particular condition, and I'd make some modification that broke it. So while it technically works, it's not really a good idea.
[expr.add], ¶5
所以它是 UB,因为结果不指向数组的任何有效元素。
[expr.add], ¶5
So it's UB, since the result do not point to any valid element of the array.
评论,实际上:(对 FelixCQ 的回答)
我可以理解为什么在循环中获取超出范围的指针可能会很危险,因为可能会展开循环和乱序求值,因此在评估终止条件之前,指针可能会被解除引用,如这个简单的示例所示:
但是,如果这是 UB 的原因,则
存在完全相同的问题!或者我错过了什么?
comment, acctually: (to FelixCQ's answer)
I could understand why obtaining an Out-of-range pointer in a loop could be dangerous because of possible loop unrolling and out-of-order evaluation, so that the pointer could get derefferenced before the terminating condition is evaluated, as in this simple example:
However, if this is the reason for UB, then
has exactly the same problem! Or am I missing something?