我理解Abort trap 6
发生在你写入你不拥有的记忆的一部分时,但我在做K& R练习时意识到了一些有趣的东西。
/* strcat: copies t to the end of s */
void _strcat(char *s, char *t) {
while (*s != '\0') {
s++;
}
while ((*s++ = *t++) != '\0') { }
}
#include <stdio.h>
int main() {
char s[7] = "hello, ";
char *t = "world";
_strcat(s, t);
printf("%s\n", s);
return 0;
}
感兴趣的部分是char s[7] = "hello, "
。
当数组的大小为7时,"hello, "
,Abort trap 6
的确切长度不打印,即使_strcat
在初始化的部分之外添加了字符记忆。
8到12之间的任何数字(包括)都会得到Abort trap 6
,而<> = 13的数字则可以。
因此出现了两个问题:
char s[12] = "hello, "
为什么7
不合适?尾随13
似乎需要一个大小为'\0'
的数组,但为什么7可以呢?不应该是8?7
首先是好的?大小8-12包含"hello, "
,就像一个7号字符大小的数组一样,并且写得超出了它们原来的数组大小,但是7
却没有使用它,而其他人没有。答案 0 :(得分:1)
你必须阅读机器代码来解决这个问题。正如Jonathan Leffler所说,这是不确定的行为。
它可能取决于编译器以及它如何在内存中放置内容。不要求大小为7的数组获得实际的7个字节。它可能决定将其填充到16以获得更好的堆栈布局。或者它可能会将它放在不同的位置,因此在它之后有一个零和一些额外的空间,而较大的阵列会有不同的位置。
或者如果您使用优化进行编译,编译器可能会将大小为7的循环展开为“正确”代码,这会减少为简单puts("hello, world");
,但无法内联更大的循环。
我出于好奇而做了一个小实验,而在Linux上使用GCC,答案是在64位模式下它始终有效,因为在存储char *t
的8字节"world"
指针中有足够的空间
在32位模式下,它会因为您描述而失败,因为它会覆盖返回堆栈。但是有7种工作,有垃圾数据,因为它在超过返回值之前没有找到零,然后它“追加”到开放堆栈空间。打印结果类似于hello, ��#m�?��world
答案 1 :(得分:0)