Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.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类堆_C_Heapsort - Fatal编程技术网

c类堆

c类堆,c,heapsort,C,Heapsort,好的,我需要用c语言创建一个“通用”堆,这就是我到目前为止所做的 (我可能在代码中缺少一些结束括号,但当我将代码移到这里时,它们就丢失了) void srtheap(void*,size\u t,size\u t,int(*)(常量void*,常量void*)); void heapify(void*,size\u t,size\u t,size\u t,int(*)(常量void*,常量void*)); void srtheap(void*base,size\u t nelem,size\u

好的,我需要用c语言创建一个“通用”堆,这就是我到目前为止所做的 (我可能在代码中缺少一些结束括号,但当我将代码移到这里时,它们就丢失了)

void srtheap(void*,size\u t,size\u t,int(*)(常量void*,常量void*));
void heapify(void*,size\u t,size\u t,size\u t,int(*)(常量void*,常量void*));
void srtheap(void*base,size\u t nelem,size\u t size,int(*比较)(const void*,const void*)){
无效*p1,*p2;
void*last=base+(尺寸*(nelem-1));
用于(尺寸\u t curpos=nelem-1;curpos>0;curpos-2){
p1=基底+((curpos-1)/2)*尺寸;
如果(compar(last,(last size))>=0{
如果(比较(最后一个,p1)>0){
交换(最后,p1,大小);
heapify(基部、内勒、curpos、尺寸、比较器);
}
}
else{//LEFT>RIGHT
如果(比较(最后大小,p1)>0){
交换(最后一个大小,p1,大小);
heapify(底座、内勒、curpos-1、尺寸、比较器);
}
//否则,父项大于左和右,
//或者父项已与子项交换,迭代已完成,重复循环
}//end else,已将子项与父项进行比较
//结束两个子项的检查,如果跳过此循环,则只剩下左个子项
最后一个=最后一个-(2*尺寸);
}
/*
**现在heapify和sort数组
*/
while(nelem>0){
最后一个=基础+(尺寸*(nelem-1));
交换(基本、最后、大小);
nelem=nelem-1;
heapify(base,nelem,0,size,compar);//传入数组,#元素,起始位置,比较
}
}
void heapify(void*root、size\t numel、size\t pos、size\t sz、int(*比较)(const void*、const void*)){
无效*rc、*lc、*p1;
while(pos=0){
如果(比较(rc,p1)>0){
掉期(rc、p1、sz);
pos=(pos+1)*2;//向右移动,heapify
}
否则{
pos=numel;//父项>左和右,数组现在已重设
}
}//右结束>左结束
else{//LEFT>RIGHT
如果(比较(lc,p1)>0){
掉期(信用证、信用证、深交所);
pos=((pos+1)*2)-1;//向左移动,heapify
}
否则{
pos=numel;//父项>左和右,数组现在已重设
}//结束内部if,else
}//结束左,右比较
}//结束右键检查
否则如果((pos+1)*2)-10){
掉期(信用证、p1、sz);
pos=((pos+1)*2)-1;//向左移动,继续heapify
}
否则{
pos=numel;//PARENT>左侧,数组现在已重设
}
}//左转向结束检查
否则{//当前元素没有子元素,数组暂时已重设
pos=努美尔;
}
}
}
此外,我有一个主文件,其中包括一个比较函数。 基本上,数组的基址、元素数量、每个元素的大小以及比较函数都被传递到我的heapsort函数中

当我运行程序时,我得到了一个分段错误,我认为这意味着我试图访问未分配给我的内存。 所以我想我在想,有没有人看到我访问非法内存地址的问题,或者可以给我指一个调试器,我可以用它来解决问题


谢谢

调试器在诊断内存错误源时通常很有用。让我们知道从调试器运行代码时会发生什么

for (size_t curpos = nelem-1; curpos>0; curpos-2){
curpos-2
没有任何效果。你是说
-
还是
-=2

此外,严格来说,您不能对
void*
指针执行指针算术,即使编译器允许,也不要依赖它。相反,将其转换为
char*
,这样可以保证
ptr+x
只添加
x
字节,而不是
x
的倍数

您可能还会发现,创建宏来索引元素数组也很有用。这将使您的代码更具可读性:

#define ELEM(base, i) ((char *)(base) + (i)*size)

您可以使用gdb来帮助调试这个。首先,使用
-g
编译程序以启用调试符号。然后运行:
gdb heapsort
,其中heapsort是程序的名称。然后键入
run
,点击enter,然后等待它崩溃。有用的命令包括用于回溯的
bt
和用于打印变量值的
p

您使用的是什么平台?由于您说的是“segmentation fault”,这通常是您从Unix/Linux获得的消息,所以我假设您使用的是其中的一种。如果您使用gcc编译,请使用
-g
标志构建以启用调试符号,然后运行代码(这是一个指向简单gdb教程的链接)。是的,我使用的是SunOS,我将查看gdb,看看是否有任何成功之处。由于更好的安全性,谢谢斯建议使用内联函数而不是宏函数。@ sGeVic:这是C,不是C++。谢谢我在for循环中找到的,所以当我最初声明指针时,应该看起来更像char *p1,*p2;和char*last=(char*)base+(nelem-1)*size?@casablanca:我是说:-)为什么你认为宏比C中的内联函数更受欢迎?你真的应该制作一个类型为
unsigned char*
的新指针变量,并立即将
void*
转换成它,然后停止使用
void*
,因为它在算术中不可用。因此,当我在gdb中运行我的程序时,我得到一个SIGSEGV故障,返回跟踪:程序接收信号SIGSEGV,分段故障。0x1080c英寸??()(gdb)bt#0 0x1080c英寸??()#1 0x10ad8英寸??()#2 0x10774英寸??()那么我的程序在第一行代码失败了吗?用-g编译,然后重新启动程序。当程序崩溃时,使用命令“list”、“backtrace”、“up”和“down”。祝你好运
#define ELEM(base, i) ((char *)(base) + (i)*size)