解释这个C代码的输出?

时间:2010-08-14 04:36:17

标签: c

我今天编写了这段代码,仅仅是出于实验,而我正试图弄清楚输出。

 /*
  * This code in C attempts to exploit insufficient bounds checking
  * to legitimate advantage.
  * 
  * A dynamic structure with the accessibility of an array.
  * Handy for small-time code, but largely unreliable.
  */
 int array[1] = {0};
 int index = 0;

 put(), get();

 main ( )
 {
    put(1); put(10), put(100);
    printf("%6d %5d %5d\n", get(0), get(1), get(2));
 }

 put ( x )
 int x;
 {
    array[index++] = x;
 }

 get ( index )
 int index;
 {
    return array[index];
 }

输出:
 1 3 100

3 个答案:

答案 0 :(得分:2)

那里有一个问题,你将'array'声明为长度为1的数组,但是你要写3个值。它至少应该是'array [3]'。没有它,你正在写入未分配的内存,所以任何事情都可能发生。

它在没有修复的情况下输出'3'的原因是它输出全局'index'变量的值,这是内存中的下一个int(在你的情况下 - 正如我所说,任何事情都可能发生)。即使您使用put(10)调用覆盖了此值,索引值也会用作赋值中的索引,然后进行后递增,这会将其设置为2 - 然后在结束时将其设置为3调用put(100)并随后通过printf输出。

答案 1 :(得分:1)

这是未定义的行为,所以唯一真正的解释是“它在一台机器上执行某些操作,在其他机器上执行其他操作”。

此外,K& R函数语法是什么?

编辑:printf猜错了。就语法而言,阅读K& R第二版(封面有一个红色ANSI标记),它使用现代函数语法(以及其他有用的更新)。

答案 2 :(得分:0)

为了扩展已经说过的内容,访问越界数组成员会导致未定义的行为。未定义的行为意味着字面意思anything可能发生。没有办法利用未定义的行为,除非你深入到深奥的特定平台黑客攻击。不要这样做。

如果你想要一个“动态阵列”,你必须自己照顾它。如果您的要求很简单,您只需mallocrealloc缓冲区即可。如果您的需求更复杂,您可能希望定义一个结构,该结构保持单独的缓冲区,大小和计数,并编写对该结构进行操作的函数。如果您只是学习,请尝试两种方式。

最后,您的函数声明语法是有效的,但是过时了。这种形式很少见,在新代码中几乎闻所未闻。将put声明为:

int put(int x) {…}

始终将main声明为:

int main(int argc, char **argv) {…}

argcargv的名称并不重要,但类型是。如果你忘记了这些参数,恶魔就会飞出你的鼻子。