gpt4 book ai didi

C 段错误巫术

转载 作者:太空宇宙 更新时间:2023-11-04 03:51:38 25 4
gpt4 key购买 nike

在下面的代码中我得到了一个 sementation 错误但是 when I add a\n at the end of printf ("* I started to learn C!! \n ");它解决了问题。有什么想法吗?

#include <stdio.h>
#include <string.h>

char* draw_line(int line_len, const char style) {
int i;
char *line;
char s_style[2] = {style, '\0'};

strcpy(line, "\n");
for(i=0; i<line_len; i++) {
strcat(line, s_style);
}
printf("%s\n", line); //debug
return line;
}

int main() {

char *line;

printf ("* I started to learn C!! ");
line = draw_line(5, '*');
// printf("%s\n", line);

return 0;
}

最佳答案

至少这些行是个问题(不是中间那一行,只是为了上下文保留它):

char *line; 
char s_style[2] = {style, '\0'};
strcpy(line, "\n");

这里 line 是未初始化的,这意味着它将在 line 存储位置的堆栈中发生任何事情。然后这个“随机”地址被 strcpy 获取,它将那个两字节的字符串复制到那里。

如果地址位于您不允许写入的位置,那么您很幸运,您的程序因段错误而崩溃,调试器会在堆栈跟踪中向您显示问题行。

但是,如果地址恰好是一个可写的内存位置,那么那里的任何内容都会被覆盖。然后会发生什么,所有的赌注都没有了。它可能是未使用的内存,没有任何反应。它可能是一些文本,你只会在某处得到损坏的文本,它可能是一些重要的变量,这会让你的程序表现得很有趣。它可能是堆栈中的返回地址,导致您的程序在跳转到损坏的地址时执行完全意外的操作。 Stack 可以保留之前函数调用和局部变量留下的各种值,因此 address 甚至很可能包含来自其他指针的值。

但问题是,当您更改代码时,以任何方式留在堆栈中的值以及未初始化变量采用的值都可以而且确实会发生变化,因此任何更改都会使您的代码表现不同。这可能是您添加 printf 时发生的情况。

简单地说,不要那样做。取消引用未初始化的变量是未定义的行为

为避免许多此类错误,为您的编译器启用警告并修复它们(对于 gccclang,命令行开关 -Wall -Wextra 是任何新代码的好组合)。

关于C 段错误巫术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20272593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com