Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用FOR循环时出现分段错误,但在指针数组的qsort实现中使用WHILE时出现分段错误_C_For Loop_Segmentation Fault_Qsort_Kernighan And Ritchie - Fatal编程技术网

C 使用FOR循环时出现分段错误,但在指针数组的qsort实现中使用WHILE时出现分段错误

C 使用FOR循环时出现分段错误,但在指针数组的qsort实现中使用WHILE时出现分段错误,c,for-loop,segmentation-fault,qsort,kernighan-and-ritchie,C,For Loop,Segmentation Fault,Qsort,Kernighan And Ritchie,我目前开始学习C编程,我的长期目标是自学逆向工程,我正在学习丹尼斯·M·里奇的优秀著作。尽管这本书写于90年代,但我还是选择了这本书,因为作者在书中的解释和例子都非常仔细。 无论如何,我在玩作者在5.6节中描述的快速排序算法,并试图通过回忆重写它,但由于我试图用gdb调试的分段错误而遇到了问题。代码是: #include <stdio.h> #define MAX 10000 void sort(int **, int, int); int main(){ int tab

我目前开始学习C编程,我的长期目标是自学逆向工程,我正在学习丹尼斯·M·里奇的优秀著作。尽管这本书写于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
更改为
,而
循环产生了不同。。。
注意,我在ubuntu 16.04上使用GCC

谢谢大家的关注,很抱歉说得太多了。 亲切问候,,
美国。

您的while循环实际上与for循环不同。while循环在使用它之前递减i;for循环没有。

您的while循环实际上与for循环不同。while循环在使用它之前递减i;for循环不在以下位置。

for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
循环从上一个循环的最后一个值
i
开始,在那里它到达数组的末尾(因此
i
将是
MAX
),或者在它为零的点上索引
tab

在第一种情况下,
ptrtab[MAX]
将被索引,这是无效的;在第二种情况下,将使用未初始化的
ptrtab
条目,它是一个自动变量,将具有随机值(指向随机内存位置,这可能是无效的(未定义的行为)。

for (;i>0;i--) printf ("%d\n",*ptrtab[i]);
循环从上一个循环的最后一个值
i
开始,在那里它到达数组的末尾(因此
i
将是
MAX
),或者在它为零的点上索引
tab



在第一种情况下,
ptrtab[MAX]
将被索引,这是无效的;在第二种情况下,将使用未初始化的
ptrtab
条目,它是一个自动变量,将具有随机值(指向随机内存位置,这可能是无效的(未定义的行为).

这本书不教现代和标准C。@Olaf谢谢你的评论。你知道一些这样做的电子书或教程吗?标准是一本好书。但是在某个地方有一个书单。这本书不教现代和标准C。@Olaf谢谢你的评论。你知道一些这样做的电子书或教程吗?标准是这本书读得不错。但是在某个地方有一个书单。将sentinel添加到选项卡是一种方法。另一种方法是避免完全定义
MAX
(只需编写
tab[]={…}
),而不必为ptrtab数组操心(只需编写
tab+i
,无论您在哪里编写
ptrtab[i]
),并使用
进行迭代(int*start=tab;start
@williampersell:sentinel已经实现。第一个循环仅在
..&&tab[i]时运行>0
@jarmod:没有初始值设定项的数组中的剩余元素不是隐式初始化为0吗?@Gerhardh是的,我相信你是正确的,我的错误。全局作用域数组显然已归零,但看起来像是自动的,初始值设定项少于数组的宽度(例如int arr[10]={1,2,3})也被初始化为零。已经删除了我答案中的这一部分,谢谢。@jarmod谢谢你的回答,我选择它是因为你先回答了,而且回答得很简洁明了:)将哨兵添加到选项卡是一种方法。另一种方法是避免完全定义
MAX
(只需编写
tab[]={…}
),不必为ptrtab数组操心(只要写
tab+i
,只要写
ptrtab[i]
),并用
迭代(int*start=tab;start
@williampersell:sentinel已经实现。第一个循环只在
..&&tab[i]时运行>0
@jarmod:没有初始值设定项的数组中的剩余元素不是隐式初始化为0吗?@Gerhardh是的,我相信你是正确的,我的错误。全局作用域数组显然已归零,但看起来像是自动的,初始值设定项少于数组的宽度(例如int arr[10]={1,2,3})也被初始化为零。已经删除了我答案的这一部分,谢谢。@jarmod谢谢你的回答,我选择它是因为你先回答了,而且它很简洁,切中要害:)可能,但更可能的是,
I
开始于
tab[I]>0
不再为真和
ptrtab[I]
没有初始化。@PaulOgilvie感谢您的回答。使用printf(“%d\n”、*ptrtab[i-1])确实解决了这个问题!也许吧,但更可能的是,
i
开始于
tab[i]>0
不再正确且
ptrtab[i]
没有初始化。@PaulOgilvie感谢您的回答。使用printf(“%d\n”,*ptrtab[i-1])确实解决了这个问题!