可以在数组开始之前向后迭代到一个

时间:2011-11-07 16:02:26

标签: c arrays pointers

例如,如果我有一个字符串的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;
}

5 个答案:

答案 0 :(得分:7)

根据以下C-FAQ question\answer,我引用:

  

只要指针指向,就会定义指针运算   在相同分配的内存块内,或虚构内   “终止”元素一个过去;否则,行为是   undefined,即使指针没有被解除引用

所以我的答案是没有,在数组开始之前迭代是不行的。

也有对C标准的引用:

  • K&amp; R2 Sec。 5.3 p。 100,Sec。 5.4 pp.102-3,Sec。 A7.7 pp。 205-6
  • ISO Sec。 6.3.6(C89)或6.5.6 / 8(C99)
  • 基本原理3.2.2.3

答案 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];

有完全相同的问题!或者我错过了什么?