在指针数组的 qsort 实现中使用 FOR 循环但不使用 WHILE 时出现分段错误
Segmentation Fault when using FOR loop but not when using WHILE in an implementation of qsort on an array of pointers
我目前正在开始 C 编程,我的长期 objective 正在自学逆向工程,并且我正在阅读 Denis M. Ritchie 的优秀书籍。尽管这本书写于 90 年代,但我还是选择了这本书,因为作者非常注意书中的解释和示例。
不管怎样,我在玩作者在 5.6 节中描述的快速排序算法,并试图通过回忆重写它,但由于我试图用 gdb 调试的分段错误而遇到了麻烦。代码是:
#include <stdio.h>
#define MAX 10000
void sort(int **, int, int);
int main(){
int tab[MAX]={18,7,43,72,2365,743,234,3215,13,456}, i;
int *ptrtab[MAX];
for (i=0; i<MAX && tab[i]>0; i++){
ptrtab[i]=&tab[i];
}
sort(ptrtab, 0, i-1);
for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
return 0;
}
void sort(int **ptrtab,int gauche,int droite){
int i, dernier;
void echanger(int **, int, int);
if (gauche>=droite) return;
dernier=gauche;
for (i=gauche+1; i<=droite; i++){
if (*ptrtab[i]< *ptrtab[gauche])
echanger(ptrtab, ++dernier, i);
}
echanger(ptrtab, gauche, dernier);
sort(ptrtab,dernier+1,droite);
sort(ptrtab,gauche, dernier);
}
void echanger(int **ptrtab,int a,int b){
int *temp=ptrtab[a];
ptrtab[a]=ptrtab[b];
ptrtab[b]=temp;
}
长话短说,在确定原因 (for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
) 中的行后,我对其进行了中断,分段错误在 for 循环的第一次迭代中使程序崩溃,并且 printf
没有被执行。所以我只是在代码中更改了这一行,改为放置 while
循环:
#include <stdio.h>
#define MAX 10000
void sort(int **, int, int);
int main(){
int tab[MAX]={18,7,43,72,2365,743,234,3215,13,456}, i;
int *ptrtab[MAX];
for (i=0; i<MAX && tab[i]>0; i++){
ptrtab[i]=&tab[i];
}
sort(ptrtab, 0, i-1);
while (i>0) printf ("%d\n",*ptrtab[--i]);
return 0;
}
void sort(int **ptrtab,int gauche,int droite){
int i, dernier;
void echanger(int **, int, int);
if (gauche>=droite) return;
dernier=gauche;
for (i=gauche+1; i<=droite; i++){
if (*ptrtab[i]< *ptrtab[gauche])
echanger(ptrtab, ++dernier, i);
}
echanger(ptrtab, gauche, dernier);
sort(ptrtab,dernier+1,droite);
sort(ptrtab,gauche, dernier);
}
void echanger(int **ptrtab,int a,int b){
int *temp=ptrtab[a];
ptrtab[a]=ptrtab[b];
ptrtab[b]=temp;
}
现在这段代码可以使用了。
我知道我的代码中肯定有很多错误,因为我只是一个初学者,但我无法理解为什么从 for
更改为 while
循环会有所不同......
请注意,我在 ubuntu 16.04.
上使用 GCC
感谢大家的关注,抱歉啰嗦。
亲切的问候,
S.A.
您的 while 循环实际上与 for 循环不同。 while 循环递减 i before 使用它; for 循环没有。
在:
for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
循环从前一个循环的最后一个值 i
开始,到达数组末尾(所以 i
将是 MAX
),或者索引tab
在零点。
在第一种情况下,ptrtab[MAX]
将被索引,这是无效的,在第二种情况下,将使用 ptrtab
的未初始化条目,作为自动变量,将有一个随机值(指向随机内存位置,这可能是无效的(未定义的行为)。
我目前正在开始 C 编程,我的长期 objective 正在自学逆向工程,并且我正在阅读 Denis M. Ritchie 的优秀书籍。尽管这本书写于 90 年代,但我还是选择了这本书,因为作者非常注意书中的解释和示例。 不管怎样,我在玩作者在 5.6 节中描述的快速排序算法,并试图通过回忆重写它,但由于我试图用 gdb 调试的分段错误而遇到了麻烦。代码是:
#include <stdio.h>
#define MAX 10000
void sort(int **, int, int);
int main(){
int tab[MAX]={18,7,43,72,2365,743,234,3215,13,456}, i;
int *ptrtab[MAX];
for (i=0; i<MAX && tab[i]>0; i++){
ptrtab[i]=&tab[i];
}
sort(ptrtab, 0, i-1);
for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
return 0;
}
void sort(int **ptrtab,int gauche,int droite){
int i, dernier;
void echanger(int **, int, int);
if (gauche>=droite) return;
dernier=gauche;
for (i=gauche+1; i<=droite; i++){
if (*ptrtab[i]< *ptrtab[gauche])
echanger(ptrtab, ++dernier, i);
}
echanger(ptrtab, gauche, dernier);
sort(ptrtab,dernier+1,droite);
sort(ptrtab,gauche, dernier);
}
void echanger(int **ptrtab,int a,int b){
int *temp=ptrtab[a];
ptrtab[a]=ptrtab[b];
ptrtab[b]=temp;
}
长话短说,在确定原因 (for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
) 中的行后,我对其进行了中断,分段错误在 for 循环的第一次迭代中使程序崩溃,并且 printf
没有被执行。所以我只是在代码中更改了这一行,改为放置 while
循环:
#include <stdio.h>
#define MAX 10000
void sort(int **, int, int);
int main(){
int tab[MAX]={18,7,43,72,2365,743,234,3215,13,456}, i;
int *ptrtab[MAX];
for (i=0; i<MAX && tab[i]>0; i++){
ptrtab[i]=&tab[i];
}
sort(ptrtab, 0, i-1);
while (i>0) printf ("%d\n",*ptrtab[--i]);
return 0;
}
void sort(int **ptrtab,int gauche,int droite){
int i, dernier;
void echanger(int **, int, int);
if (gauche>=droite) return;
dernier=gauche;
for (i=gauche+1; i<=droite; i++){
if (*ptrtab[i]< *ptrtab[gauche])
echanger(ptrtab, ++dernier, i);
}
echanger(ptrtab, gauche, dernier);
sort(ptrtab,dernier+1,droite);
sort(ptrtab,gauche, dernier);
}
void echanger(int **ptrtab,int a,int b){
int *temp=ptrtab[a];
ptrtab[a]=ptrtab[b];
ptrtab[b]=temp;
}
现在这段代码可以使用了。
我知道我的代码中肯定有很多错误,因为我只是一个初学者,但我无法理解为什么从 for
更改为 while
循环会有所不同......
请注意,我在 ubuntu 16.04.
感谢大家的关注,抱歉啰嗦。 亲切的问候, S.A.
您的 while 循环实际上与 for 循环不同。 while 循环递减 i before 使用它; for 循环没有。
在:
for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
循环从前一个循环的最后一个值 i
开始,到达数组末尾(所以 i
将是 MAX
),或者索引tab
在零点。
在第一种情况下,ptrtab[MAX]
将被索引,这是无效的,在第二种情况下,将使用 ptrtab
的未初始化条目,作为自动变量,将有一个随机值(指向随机内存位置,这可能是无效的(未定义的行为)。