二维数组:使用qsort对 2维字符数组排序疑难问题调试及解决过程

先说说我这个场景中有个 2维代码段如下:
char files[101][64]; // files[i][0] sotres the length of the i-the file name
正如注释中说 files[i ][0] 用来存储 files[i ] 这个长度串是从 files[i ][1] 开始存储每个串长度保证不超过 60, 所以才考虑这样来存储现在突然发现在串都存储到 files 中去后必须还要对 files 中串进行排序如果是使用 c 来写当然没问题但是既然代码已经写成这样就没再重写而是打算用 C qsort 来排序这也是个很有挑战性工作
对于自己代码先后尝试了很多办法也没能让它正确工作最终想到调试 MSDN 上给出那个使用 qsort 对串进行排序那个如下:
# <stdlib.h>
# <.h>
# <stdio.h>

compare( const void *arg1, const void *arg2 );

void ( argc, char **argv )
{
i;
/* Eliminate argv[0] from sort: */
argv;
argc--;

/* Sort reing args using Quicksort algorithm: */
qsort( (void *)argv, (size_t)argc, ( char * ), compare );

/* Output sorted list: */
for ( i = 0; i < argc; i )
prf( "%s " , argv[i] );
prf( "\n" );
}

compare( const void *arg1, const void *arg2 )
{
/* Compare all of both s: */
_stricmp( * ( char ** ) arg1, * ( char ** ) arg2 );
}

在 qsort 句设置断点为了看看 argv 是什么指针类型 ( 是 char** 还是 char(*)) 同时看看 qsort 时传递个参数值是多少另外在 compare 上设置断点为了看看这个被回调时实参值是多少 ( 这个命令行参数是 this is a test.)
单步执行到 qsort 此时 argv type 是 char** value 是 0x003a4ee4 这段内存内容是:
0x003A4EE4 35 4f 3a 00 3a 4f 3a 00 3d 4f 3a 00 3f 4f 3a 00 00 00 00 00 64 3a 5c 4d 79 44 6f 63 75 5O:.:O:.=O:.?O:.....d:\MyDocu
0x003A4F01 6d 65 6e 74 73 5c 56 69 73 75 61 6c 20 53 74 75 64 69 6f 20 32 30 30 35 5c 50 72 6f 6a ments\Visual Studio 2005\Proj
0x003A4F1E 65 63 74 73 5c 4a 4f 4a 5c 64 65 62 75 67 5c 4a 4f 4a 2e 65 78 65 00 54 68 69 73 00 69 ects\JOJ\debug\JOJ.exe.This.i
0x003A4F3B 73 00 61 00 74 65 73 74 2e 00 fd fd fd fd ab ab ab ab ab ab ab ab fe ee fe ee fe ee fe s.a.test.....................
可以看到在 argv 值指示地址处不是而是几个指针再根据指针所指向内在查看恰恰是那几个地址这样这个就没什么难理解现在改下这个看看这个模式是不是可以在普通 2维上实现主要改动了以下代码改动后是:
char data[4][16] = { "this" , "is" , "a" , "test." };
/* Sort reing args using Quicksort algorithm: */
qsort( (void *)data, (size_t)4, ( char * ), compare );
上述对于 qsort 就是做了个替换把以前 argv 替换成了 data 把以前 argc 替换成了 4, 运行出现异常异常信息是说在 stricmp.c 文件 98 行个 assret (dst != NULL) 断言失败了于是对这个修改后进行调试看看差别在哪里:
运行到 qsort data type 是 char[4][16] value 是 0x0012ff14 查看这个内存地址发现这个内存地址处值就是那几个坏了没有个 2级指针指向它们!现在结果已经可以预料到那就是 qsort 以为传给它个 2级指针首地址 ( 但我们传给它实际上却是 data 是直接指向! ) 所以 qsort 从 data 地址开始即从 0x0012ff14 开始读取 4个字节把这 4个字节作为指针去检索内存!为了验证这个想法继续 F5 到下个断点:果然如此!执行到 compare 两个参数值是 0x0012ff14, 0x0012ff18 !
如何办!我们必须传给 qsort 这样个序列: &data[0] &data[1], &data[2], &data[3] 在调试器里面看到 &data[0] = 0x0012ff14, &data[1] = 0x0012ff24, &data[2] = 0x0012ff34, &data[3] = 0x0012ff34 现在抱着这样希望再次修改 qsort :
qsort( (void *)data, (size_t)4, ( char (*)[16] ), compare );
红字并加粗部分是我修改过这时候再调试看看但我发现自己搞错了 qsort 第 3个参数是 size_t 类型我却又传递进去个指针任何指针类型都是 4 个字节修改成这样试试:
qsort( (void *)data, (size_t)4, 16 , compare );
执行到 compare YES!!! 这次两个参数值是 0x0012ff14,0x0012ff24 但还是异常了问题出在 compare 上面次传进去指针可完全是串首地址了所以把 compare 由原来: compare( const void *arg1, const void *arg2 )
{
/* Compare all of both s: */
_stricmp( * ( char ** ) arg1, * ( char ** ) arg2 );
}
修改为:
compare( const void *arg1, const void *arg2 )
{
/* Compare all of both s: */
// _stricmp( * ( char** ) arg1, * ( char** ) arg2 );
_stricmp((char *)arg1, (char *)arg2);
}
次再运行 OK! 没有异常!
遗憾是没有改输出这次输出排序后 data 看任务成功完成!
现在回过头来解决最初那个问题相信此时已经不是问题了
现在所有问题都完美解决!原来那个问题解决思路方法已经在上面调试过程中有了!

Tags:  js二维数组 二维数组初始化 java二维数组 二维数组

延伸阅读

最新评论

发表评论