2015-12-01 30 views
1

我跑在Mac此代码,也可以在Linux:这个字符串怎么没有溢出缓冲区?

​​

在Mac上,如果我进入了“1234567890”作为命令行参数,90溢出到缓冲区中的一个,因为我所期望的,因为缓冲区的8字节被超过2.

但是,如果我在我的Linux系统上运行它,它需要更多的字符溢出缓冲区。怎么来/为什么我可以放弃在Linux中缓冲缓冲区?

同样作为一个方面说明,在两个系统上,整个字符串仍然会打印在缓冲区2中,只有溢出的项目在缓冲区1中打印。为什么会发生?剩下的角色怎么会不会进入下一个?如果这个问题表达不好,继承人一个例子:

如果我在我的mac上输入1234567890,1234567890将打印在缓冲区二,90将打印在缓冲区一。即使已经溢出了,90怎么能仍然适合缓冲区2。 (它在linux上是相同的概念,但需要超过10个字节才能溢出)

回答

1

在这两种情况下,都存在缓冲区溢出。缓冲区溢出只会调用未定义的行为。在某些情况下,它似乎工作得很好,不会产生崩溃或段错误。

例如,内存分配器(在这种情况下,堆栈分配)可能会分配略多于您请求的对齐内存的内存。在这种情况下,你可能实际上能够溢出缓冲区而没有任何明显的副作用,但这实际上是一件非常糟糕的事情,因为它隐藏了错误,而不是消除它。

在这种情况下,由于它涉及堆栈,因此您将堆栈中的内容覆盖为缓冲区分配的内容。如果您引入更多变量或开始调用函数,您可能会开始注意到非常奇怪的副作用。无论如何,这是一个非常有问题的场景,并且您希望尽可能避免缓冲区溢出。

+0

我明白它是如何缓冲区溢出,但我试图以受控方式检查它。我认为,如果我将它溢出2个字符,那么下一个缓冲区将接收这些字符。我猜你的意思是堆栈在变量之间有一些填充,所以需要更多字符才能到达另一个缓冲区。我对么? – yasgur99

+0

@ yasgur99最有可能的是 - 我们在假想的领域里,却不知道到底发生了什么(对装配的窥视可能会产生很多见解)。但是,如果没有段错误或覆盖,下面的缓冲区的内容可能会在这里脱离,这与用于正确堆栈对齐的某种填充有关。 –

+1

谢谢你sm非常有帮助 – yasgur99