C语言爆栈经历(一)

在编写类似ls -al指令的C程序时,遇到段错误问题。经排查发现,strcpy()函数的第二个参数引起错误,由于试图访问不可达的char arry[][]。解决方法是通过malloc在堆上分配内存,但即使使用static仍然存在异常,这一现象有待进一步探讨。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下面代码是用来写自己的ls -al 指令时出现的.

code:

void display_dir(int flag_param,char *path)
{
  DIR *dir;
  struct dirent *ptr;
  int count=0;



  char filenames[256][PATH_MAX+1],temp[PATH_MAX+1];

    //看这个语句,明显是从stack分配的空间



  //获取该目录下的文件总数和最长的文件名
  dir=opendir(path);
  if(dir==NULL)
  {
    my_err("opendir",__LINE__,__FILE__);
  }
  while((ptr=readdir(dir))!=NULL)
  {
    if(g_maxlen<strlen(ptr->d_name))
      g_maxlen=strlen(ptr->d_name);
    count++;
  }
  closedir(dir);

  if(count>256)
    my_err("too many files under this dir",__LINE__,__FILE__);

  int i,j,len=strlen(path);
  //获取该目录下的所有文件名
  dir=opendir(path);
  for(i=0;i<count;i++)
  {
    ptr=readdir(dir);
    if(ptr==NULL)
    {
      my_err("readdir",__LINE__,__FILE__);
    }
    strncpy(filenames[i],path,len);
    filenames[i][len]='\0';


    strcat(filenames[i],ptr->d_name);
    filenames[i][len+strlen(ptr->d_name)]='\0';

  }
    int *index=init_access_index(count);




    quick_sort(index,filenames,0,count-1,strcmp);
    //这里就是错误的入口



    //使用index访问
    for(i=0;i<count;i++)
    {
      display(flag_param,filenames[index[i]]);
    }
    closedir(dir);
    if( (flag_param & PARAM_L) == 0 )
    {
      printf("\n");
    }

}
//这个函数本质就是一个快速排序,特点是:对于字符串数组arry并不是直接排序
//而是使用数组index作为访问索引,只交换index中的位置,并不直接移动字符串;
void quick_sort(int *index, char *arry[PATH_MAX+1],int beg,int end,Cmp fun)
{
  if(beg>=end) return ;
  int i=beg;
  int j=end;
  char target[PATH_MAX+1];
  int target_pos=index[beg];
  memset(target,'\0',PATH_MAX+1);

  strcpy(target,arry[index[beg]]);
  //报错语句最终入口


  //此处索引目标千万注意,ls-la是忽略大小写和开头.的
 // printf("pos:%2d %2d %s\n",beg,target_pos,target);
  while(i<j)
  {
    while ( (i<j)&&(fun(arry[index[j]],target) >= 0) ) 
    {
      j--;
    }
    index[i]=index[j];
    //debug(index,arry,end-beg);
    while ( (i<j)&&(fun(arry[index[i]],target) <= 0) )
    {
      i++;
    }
    index[j]=index[i];
   // debug(index,arry,end-beg);
  }
  index[i]=target_pos;
  //debug(index,arry,end-beg);
  quick_sort(index,arry,beg,i-1,fun);
  quick_sort(index,arry,i+1,end,fun);
}

当执行:./book -la ./时出现明显段错误;

最错误原因是strcpy()的第二个参数异常;

#堆栈捕捉
(gdb) bt
#0  __strcpy_sse2_unaligned () at ../sysdeps/x86_64/multiarch/strcpy-sse2-unaligned.S:63
#1  0x0000555555554dfc in quick_sort (index=0x555555760460, arry=0x7fffffefce40, beg=0, end=14, fun=0x7ffff7ac9520 <__strcmp_sse2_unaligned>) at book.c:70
#2  0x000055555555577c in display_dir (flag_param=3, path=0x7fffffffd050 "./") at book.c:340
#3  0x0000555555555afc in main (argc=3, argv=0x7fffffffe168) at book.c:436

调用者最终错误原因:arry[]不能访问,

(gdb) p *arry@end
$2 = {0x632e6e69616d2f2e <error: Cannot access memory at address 0x632e6e69616d2f2e>, 0x0 <repeats 13 times>}
##很明显空间是有分配的但是不能访问.就是需要空间过大,导致在函数调用的时候出现临时变量被函数调用过程中保存上下文,使得变量被覆盖.

结果将调用者的char arry[][]改成malloc从堆中分配就没有这个错误.但是改成静态(static)还是有问题,这个实在解释不了;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值