非常奇怪的C行为

时间:2012-03-11 10:30:25

标签: c++ c

在以下简单程序中发生了一件非常奇怪的事情。该程序采用2位数的ASCII数字,因为我只需要读取数字,“@”符号和“。”符号。并找出这个字节的ASCII符号是什么。

int main(int args, char* argv[])
{
 unsigned int ch;


char aux[256];

 strcpy(aux,argv[1]);

 char a[0];

 char buff[50];
 char result[512];
 int i=0;

 while(i lessThan strlen(argv[1]))
 {   
     a[0]=aux[i];
     a[1]=aux[i+1];
     a[2]='\0';
     ch = atoi(a);
      printf("el int:%d \n",ch);
      sprintf(buff,"%c",ch);

       printf("el char: %s \n", buff);
       i=i+2;
   }

 } 

好的,这是有效的,并且在变量buff中以正确的方式打印所有ASCII符号。但是你可以看到我有一个从未使用的char[]调用结果。所以我删除它。当我再次运行程序时,我得到了不同的结果:O。由于某种原因,该程序不会读取'。'字符了:(为什么????请有人解释我,我很害怕哈哈!

我的结果带有变量结果声明:

 ./try3 494650526450

    el int:49

    el char: 1 

    el int:46 

    el char: . 

    el int:50 

    el char: 2 

    el int:52 

    el char: 4 

    el int:64 

    el char: @ 

    el int:50 

    el char: 2 

我的结果带有变量结果声明:

 ./try3 494650526450

    el int:49 

    el char: 1 

    el int:0 

    el char:  

    el int:50 

    el char: 2 

    el int:52 

    el char: 4 

    el int:64 

    el char: @ 

    el int:50 

    el char: 2 

3 个答案:

答案 0 :(得分:5)

您使用的是zero-length array,GNU扩展程序。将char a[0];更改为char a[3];。声明另一个未使用的char数组会更改内存的布局,这就是它“工作”的原因。

答案 1 :(得分:2)

立即错误是使用一个空数组:char a[0]声明一个没有元素的数组(在C ++中是非法的;我不擅长C但我认为在这种情况下它也被禁止C)。这个数组必须至少有3个元素。

除此之外,这个程序充满了问题。我发现的那些:

  • 显然缺少标题<stdio.h><string.h><stdlib.h>
  • 在访问第一个参数之前未检查传递的参数数量
  • 当数组strcpy()时,第一个参数的长度不会被考虑(这应该是strncpy()
  • 如前所述char a[0];声明一个空数组
  • lessThan不属于C或C ++
  • i是有符号整数,而strlen()返回无符号整数,混合符号比较通常是个坏主意(尽管在这种情况下它们不会产生问题)
  • 确定每个迭代器中字符串长度的长度很慢
  • 打印到字符串时,您通常要使用snprintf()(尽管在这种情况下,数组不会被覆盖)

答案 2 :(得分:1)

您已经使用零长度数组char a[0]并访问最多三个元素。因此,您需要至少分配3个位置char a[3]

输出的可能原因是,当您访问result或更多时,堆栈上a的分配与a[1]数组相邻,它将在边界外访问a的长度(因为它是0长度),并且几乎插入到其他数组的内存位置。在这样的位置写入会破坏该位置的数据。