C:strncpy比分配的字符多,然后打印。。。意外输出?
在教授给出的一些示例代码中:C:strncpy比分配的字符多,然后打印。。。意外输出?,c,printf,buffer-overflow,strcpy,C,Printf,Buffer Overflow,Strcpy,在教授给出的一些示例代码中: #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; printf( "%s\n", alpha ); printf( "%c\n", alpha[8] ); alpha[8] = 'Z'; /* segmentation faul
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
printf( "%s\n", alpha );
printf( "%c\n", alpha[8] );
alpha[8] = 'Z'; /* segmentation fault if alpha is declared statically! */
printf( "%d\n", sizeof( alpha ) );
printf( "%d\n", strlen( alpha ) );
char x[10];
strncpy( x, alpha, 26 );
/* strncpy() will NOT copy or append a '\0' */
printf( "%s\n", x );
return EXIT_SUCCESS;
}
我认为,由于strncpy不以null终止字符串,所以当打印X
时,它实际上可能打印alpha
的完整值,但实际上,它正在打印所有alpha
,然后再打印一些alpha
有人能在这里提供一些见解吗?你真幸运。写入超出数组边界的内容会导致未定义的行为 未定义的行为意味着任何行为都是可能的,它总是不需要导致分段错误,它只是意味着程序无效,并且可能显示任何行为
是的,你的程序有时看起来甚至可以按预期工作,但它仍然是符合标准的完整程序 你只是越来越幸运了。写入超出数组边界的内容会导致未定义的行为
char x[10]; strncpy( x, alpha, 26 );
/* strncpy() will NOT copy or append a '\0' */
printf( "%s\n", x );
未定义的行为意味着任何行为都是可能的,它总是不需要导致分段错误,它只是意味着程序无效,并且可能显示任何行为
是的,你的程序有时看起来甚至可以按预期工作,但它仍然是符合标准的完整程序
char x[10]; strncpy( x, alpha, 26 );
/* strncpy() will NOT copy or append a '\0' */
printf( "%s\n", x );
向strncpy传递26作为n的值,因此它复制26个字符,但当使用printf打印时,printf将尝试搜索“\0”作为字符串的终止字符。在本例中,不知何故“\0”恰好出现在“klmnopqrstuvxyz”之后
所以,在现实中,当你做一个超出边界的数组时,你可以得到任何类型的结果,一个崩溃,一个太长的字符串等等
向strncpy传递26作为n的值,因此它复制26个字符,但当使用printf打印时,printf将尝试搜索“\0”作为字符串的终止字符。在本例中,不知何故“\0”恰好出现在“klmnopqrstuvxyz”之后
因此,在现实中,当您执行一个超出边界的数组时,您可能会得到任何类型的结果、崩溃、过长的字符串等。问题在于内存布局。
在这个程序中,“alpha”就在“x”后面。所以当你打电话的时候
strncpy( x, alpha, 26 );
alpha的数据正在修改。
问题是关于内存布局。
在这个程序中,“alpha”就在“x”后面。所以当你打电话的时候
strncpy( x, alpha, 26 );
alpha的数据正在修改。使用此代码:
char x[10];
strncpy( x, alpha, 26 );
您正在将26个字节的数据复制到10个字节的数组中,这意味着您正在覆盖与“x”相邻的16个字节的内存。在这种情况下,看起来与“x”相邻的部分是“alpha”,所以您对初始数组的一部分进行了重击
当您“printf”x时,它会一直打印,直到找到一个空字节,所以它会打印出您复制的所有26个字节,以及内存中的任何内容(“alpha”)直到下一个空字节。使用此代码:
char x[10];
strncpy( x, alpha, 26 );
您正在将26个字节的数据复制到10个字节的数组中,这意味着您正在覆盖与“x”相邻的16个字节的内存。在这种情况下,看起来与“x”相邻的部分是“alpha”,所以您对初始数组的一部分进行了重击
当您“printf”x时,它会一直打印,直到找到一个空字节,所以它会打印出您复制的所有26个字节,以及内存中的任何内容(“alpha”的剩余内容)直到下一个空字节。我希望有一个确定的原因,
klmnopqrstuvxyz
将在abcdefghzjklmnopqrstuvxyz
之后直接打印出来;我认为如果空字符位于Z之后,则不会显示K-Z第二次输出。您只复制了26个字符,因此在alpha中可能出现在“Z”之后的空字符不会被复制。但是,数组越界仍然不能保证任何东西,因为对于x,只分配了10个字节,x的第10个字节后的内存不属于您,可以以任何方式操作。我希望有一个确定的原因,KLMNOPQRSTUVWXYZ
将在ABCDEFGHZJKLMNOPQRSTUVWXYZ
之后直接打印出来;我认为如果空字符位于Z之后,则不会显示K-Z第二次输出。您只复制了26个字符,因此在alpha中可能出现在“Z”之后的空字符不会被复制。但是,数组越界仍然不能保证任何东西,因为对于x,只分配了10个字节,x的第10个字节之后的内存不属于您,可以在任何情况下操作