Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:strncpy比分配的字符多,然后打印。。。意外输出?_C_Printf_Buffer Overflow_Strcpy - Fatal编程技术网

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个字节之后的内存不属于您,可以在任何情况下操作