C分段故障伏都教

时间:2013-11-28 18:18:57

标签: c segmentation-fault

在下面的代码中,我遇到了分段错误 但是当我在printf的末尾添加一个\ n时(“*我开始学习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;
}

1 个答案:

答案 0 :(得分:1)

至少这些行是一个问题(不是中间问题,只是将其保留在上下文中):

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

此处line未初始化,这意味着它将在堆栈中存储line的位置。然后这个“随机”地址由strcpy获取,它在那里复制那个双字节字符串。

如果地址位于您不允许写入的位置,您很幸运,您的程序崩溃时出现分段错误,调试程序会显示堆栈跟踪中的问题行。

但是,如果地址恰好是可写存储器位置,那么无论何处写入都会被写入。然后会发生什么,所有的赌注都没有了。它可能是未使用的内存,没有任何反应。它可能是一些文本,你只会在某处获得损坏的文本,它可能是一些重要的变量,它将使你的程序行为有趣。它可能是堆栈中的返回地址,导致程序在跳转到损坏的地址时执行完全意外的操作。堆栈可以从前面的函数调用和局部变量中获得所有类型的值,因此地址甚至可能包含来自其他指针的值。

但问题是,当您更改代码时,无论如何,堆栈中剩余的值以及未初始化的变量都会发生变化,因此任何更改都会使您的代码行为不同。这可能是您添加printf时发生的情况。

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

为了避免这样的许多错误,请为编译器启用警告并修复它们(对于 gcc clang ,命令行开关-Wall -Wextra是一个很好的组合任何新代码。)