mck*_*mck 4 c memory-management
在处理C字符串时,我遇到了这种奇怪的行为.这是K&R书中的练习,我应该编写一个函数,将一个字符串附加到另一个字符串的末尾.这显然要求目标字符串分配足够的内存,以便源字符串适合.这是代码:
/* strcat: Copies contents of source at the end of dest */
char *strcat(char *dest, const char* source) {
char *d = dest;
// Move to the end of dest
while (*dest != '\0') {
dest++;
} // *dest is now '\0'
while (*source != '\0') {
*dest++ = *source++;
}
*dest = '\0';
return d;
}
Run Code Online (Sandbox Code Playgroud)
在测试期间,我编写了以下内容,期望在程序运行时发生段错误:
int main() {
char s1[] = "hello";
char s2[] = "eheheheheheh";
printf("%s\n", strcat(s1, s2));
}
Run Code Online (Sandbox Code Playgroud)
据我所知,s1得到一个6 chars分配的数组,s2 得到一个13的数组chars.我认为当strcat尝试在高于6的索引处写入s1时,程序会出现段错误.相反,一切正常,但程序不会干净地退出,而是:
helloeheheheheheh
zsh: abort ./a.out
Run Code Online (Sandbox Code Playgroud)
并退出代码134,我认为这只是意味着中止.
为什么我没有得到段错误(如果在堆栈上分配字符串,则覆盖s2)?内存中的这些字符串(堆栈或堆)在哪里?
谢谢你的帮助.
我认为当strcat尝试写入
s1高于6该程序的索引时会发生段错误.
在堆栈上分配的内存范围之外写入是未定义的行为.通常(但不总是)调用此未定义的行为会导致段错误.但是,您无法确定是否会发生段错误.
维基百科链接很好地解释了它:
当发生未定义行为的实例时,就语言规范而言,任何事情都可能发生,也许什么都没发生.
因此,在这种情况下,您可能会遇到段错误,程序可能会中止,或者有时可能会运行正常.或者,任何事情.没有办法保证结果.
内存中的这些字符串(堆栈或堆)在哪里?
由于您已将它们声明为char []内部main(),因此它们是具有自动存储的阵列,出于实际目的,它们意味着它们位于堆栈中.