我正在处理一个关于seg故障的示例:
char m[10]="dog";
strcpy(m+1,m);
在我的centOs机器中,结果如预期:分割错误。但是在Ubuntu上什么都没发生。然后我添加一个printf("%s",m);到ubuntu上的代码,令人惊讶的是,我得到了"ddog"结果。我使用的是GCC,ubuntu版本是最新的。有人能告诉我为什么结果不一样吗。我也在raspbian上检查了它,我也收到了分割错误。
谢谢,
这会导致未定义的行为。CCD_ 1可以仅在不重叠的区域之间使用。
要修复此代码,您可以编写:
memmove(m+1, m, strlen(m) + 1);
m
的内存为:
+---+---+---+---+---+---+---+---+---+---+
| | | | | | | | | | |
+---+---+---+---+---+---+---+---+---+---+
当你用初始化它时
char m[10] = "dog";
对前四个元件CCD_ 3进行初始化。其余部分已初始化。
+---+---+---+----+---+---+---+---+---+---+
| d | o | g | | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
我使用?
来指示未初始化的内存位置。他们可以包含任何内容。
让我们走过的执行过程
strcpy(m+1, m);
循序渐进。
步骤1:将m[0]
复制到m[1]
。所以你有:
+---+---+---+----+---+---+---+---+---+---+
| d | d | g | | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
步骤2:将m[1]
复制到m[2]
。所以你有:
+---+---+---+----+---+---+---+---+---+---+
| d | d | d | | ? | ? | ? | ? | ? | ? |
+---+---+---+----+---+---+---+---+---+---+
步骤3:将m[2]
复制到strcpy
0。所以你有:
+---+---+---+---+---+---+---+---+---+---+
| d | d | d | d | ? | ? | ? | ? | ? | ? |
+---+---+---+---+---+---+---+---+---+---+
strcpy
在遇到源中的空字符时终止论点正如您所看到的,strcpy
的终止条件永远不会满足。因此,程序继续从内存中读取超出有效限制和将数据写入内存超出有效限制。
这就是未定义行为的原因。
要获得所需的结果,"ddog"
,您可以使用:
size_t len = strlen(m);
for ( int i = len; i >= 0; --i )
{
m[i+i] = m[i];
}