我是新的编码和C,并不能找到一个解释,这可以有人解释我吗:Piece of my code为什么最后两个随机字符弹出,如果我输入8,但如果我输入6它不出来。它是与空字符或什么?请我需要一个解释。我试了几乎所有的方法,仍然找不到解释。
lhcgjxsq1#
在C语言中,字符串需要以一个特殊字符NUL termination character结尾,该字符的值为0。如果您将字符串传递给printf(%s),则它希望该字符串以0结尾。由于没有设置NUL终止,因此printf函数不知道何时停止从字符串阅读字符。这称为buffer over read:您正在阅读分配给您的缓冲区(在这种情况下为aster)。确保终止aster,它将工作。实现此目的的一种方法是将char aster[n];更改为char aster[n+1];(为NUL终止字符再分配一个字符),然后设置aster[n] = 0;。考虑n = 3内存将是这样的:(OUT OF BOUNDS表示之后的内存不属于aster,而是其他东西,我们不知道它是什么)。
NUL
0
%s
printf
aster
char aster[n];
char aster[n+1];
aster[n] = 0;
n = 3
aster[0] = ? aster[1] = ? aster[2] = ? aster[3] = ? <OUT OF BOUNDS> aster[4] = ? <OUT OF BOUNDS> aster[5] = ? <OUT OF BOUNDS> aster[6] = ... and so on
你的代码记忆后会看起来像这样:
aster[0] = * aster[1] = * aster[2] = * aster[3] = ? <OUT OF BOUNDS> aster[4] = ? <OUT OF BOUNDS> aster[5] = ? <OUT OF BOUNDS> aster[6] = ... and so on
printf会查看每个字符。它应该在aster[3]处停止,但它不知道,因为在那个地方没有定义好的字符。这就是为什么它有时可能工作,但有时却不工作。它是undefined behaviour。将代码更改为始终设置NUL字符,它将如下所示:
aster[3]
aster[0] = * aster[1] = * aster[2] = 0 aster[3] = ? <OUT OF BOUNDS> aster[4] = ? <OUT OF BOUNDS> aster[5] = ? <OUT OF BOUNDS> aster[6] = ... and so on
在这种情况下,printf将永远不会读取超过aster[2]的数据。在任何情况下,读取或写入内存缓冲区都是绝对禁止的;)您还需要将循环变量i初始化为0。
aster[2]
i
1条答案
按热度按时间lhcgjxsq1#
在C语言中,字符串需要以一个特殊字符
NUL
termination character结尾,该字符的值为0
。如果您将字符串传递给printf(
%s
),则它希望该字符串以0
结尾。由于没有设置
NUL
终止,因此printf
函数不知道何时停止从字符串阅读字符。这称为buffer over read:您正在阅读分配给您的缓冲区(在这种情况下为
aster
)。确保终止
aster
,它将工作。实现此目的的一种方法是将
char aster[n];
更改为char aster[n+1];
(为NUL
终止字符再分配一个字符),然后设置aster[n] = 0;
。考虑
n = 3
内存将是这样的:(OUT OF BOUNDS表示之后的内存不属于aster
,而是其他东西,我们不知道它是什么)。你的代码记忆后会看起来像这样:
printf会查看每个字符。它应该在
aster[3]
处停止,但它不知道,因为在那个地方没有定义好的字符。这就是为什么它有时可能工作,但有时却不工作。它是undefined behaviour。将代码更改为始终设置
NUL
字符,它将如下所示:在这种情况下,
printf
将永远不会读取超过aster[2]
的数据。在任何情况下,读取或写入内存缓冲区都是绝对禁止的;)
您还需要将循环变量
i
初始化为0
。