下面代码是用来写自己的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)还是有问题,这个实在解释不了;