C 健康时的分段错误
我只是简单地用C来处理数组。但在运行时,它给了我分段错误(内核转储)。。。我不知道我在哪里尝试访问未分配的内存C 健康时的分段错误,c,C,我只是简单地用C来处理数组。但在运行时,它给了我分段错误(内核转储)。。。我不知道我在哪里尝试访问未分配的内存 #include<stdio.h> int n; int left(i) { return (2*i); } int right(i) { return (2*i + 1); } void min_heap(int a[],int i) { int l=left(i); int r=right(i); int min;
#include<stdio.h>
int n;
int left(i)
{
return (2*i);
}
int right(i)
{
return (2*i + 1);
}
void min_heap(int a[],int i)
{
int l=left(i);
int r=right(i);
int min;
if((l<=n)&&(a[l]<=a[i])&&(a[l]<=a[r]))
{
min=a[l];
a[i]=a[i]+a[l];
a[l]=a[i]-a[l];
a[i]=a[i]-a[l];
}
else if((r<=n)&&(a[r]<=a[i])&&(a[r]<=a[l]))
{
min=a[r];
a[i]=a[i]+a[r];
a[r]=a[i]-a[r];
a[i]=a[i]-a[r];
}
min_heap(a,min);
}
int main()
{
printf("The no is : ");
scanf("%d",&n);
int i,a[n+1];
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(i=n/2;i>=1;i--)
{
min_heap(a,i);
}
for(i=1;i<=n;i++)
{
printf("%d",a[i]);
}
return 0;
}
#包括
int n;
int左(i)
{
报税表(2*i);
}
右整数(i)
{
返回(2*i+1);
}
void min_堆(int a[],int i)
{
int l=左(i);
int r=右(i);
int-min;
如果((l当i==n/2
时调用min\u heap(a,i)
在这种情况下,在min\u heap()
内部,对right()
的调用将有效返回:
(2 * (n/2) + 1)
当n
为偶数时,将导致右索引n+1
,并且访问a[r]
(使用r==n+1
)超出了您分配的数组的末尾
我不确定这是否是你犯错的原因,我想可能还有其他问题
您可能应该使用调试器一步一步地完成运行。以下是Jon Bentley的一些代码,以注释形式写入C文件。完整的代码与您无关;它是通用接口,类似于bsearch()
和qsort()
,但这是用awk
编写的
/*
** See Appendix 2 of Jon Bentley "More Programming Pearls".
** See also Column 14 of Jon Bentley "Programming Pearls, 2nd Edn".
** Note that MPP algorithms are in terms of an array indexed from 1.
** C, of course, indexes arrays from zero.
**
** 1-based identities.
** root = 1
** value(i) = x(i)
** leftchild(i) = 2*i
** rightchild(i) = 2*i+1
** parent(i) = i/2
** null(i) = (i < 1) or (i > n)
**
** 0-based identities.
** root = 0
** value(i) = x(i)
** leftchild(i) = 2*(i+1)-1 = 2*i+1
** rightchild(i) = 2*(i+1)+1-1 = leftchild(i)+1
** parent(i) = (i+1)/2-1
** null(i) = (i < 0) or (i >= n) # NB: i < 0 irrelevant for unsigned numbers
*/
/*
** function swap(i, j t) {
** # x[i] :=: x[j]
** t = x[i]
** x[i] = x[j]
** x[j] = t
** }
**
** function siftup(l, u, i, p) {
** # pre maxheap(l, u-1)
** # post maxheap(l, u)
** i = u
** while (1) {
** # maxheap(l, u) except between i and its parent
** if (i <= l) break
** p = int(i/2) # p = parent(i)
** if (x[p] >= x[i]) break
** swap(p, i)
** i = p
** }
** }
**
** function siftdown(l, u, i, c) {
** # pre maxheap(l+1, u)
** # post maxheap(l,u)
** i = l
** while (1) {
** # maxheap(l, u) except between i and its children
** c = 2*i # c = leftchild(i)
** if (c > u) break;
** if (c + 1 <= u && x[c+1] > x[c]) c++
** if (x[i] >= x[c]) break
** swap(c, i)
** i = c
** }
** }
**
** function hsort( i) {
** # post sorted(1, n)
** for (i = int(n/2); i >= 1; i--)
** siftdown(i, n)
** for (i = n; i >= 2; i--) {
** swap(1, i)
** siftdown(1, i-1)
** }
** }
*/
/*
**参见Jon Bentley“更多编程珍珠”的附录2。
**另见Jon Bentley“第二版编程珍珠”第14栏。
**请注意,MPP算法是以从1索引的数组表示的。
**当然,C从零开始索引数组。
**
**基于1的身份。
**根=1
**值(i)=x(i)
**leftchild(i)=2*i
**右子女(i)=2*i+1
**家长(i)=i/2
**空(i)=(i<1)或(i>n)
**
**基于0的标识。
**根=0
**值(i)=x(i)
**leftchild(i)=2*(i+1)-1=2*i+1
**右子女(i)=2*(i+1)+1-1=左子女(i)+1
**父(i)=(i+1)/2-1
**空(i)=(i<0)或(i>=n)#注意:i<0与无符号数字无关
*/
/*
**功能交换(i,j,t){
**#x[i]:=:x[j]
**t=x[i]
**x[i]=x[j]
**x[j]=t
** }
**
**函数siftup(l,u,i,p){
**#预最大堆(l,u-1)
**#后最大堆(l,u)
**i=u
**而(1){
**#maxheap(l,u),i与其父级之间除外
**如果(i=x[i])中断
**互换(p,i)
**i=p
** }
** }
**
**函数siftdown(l、u、i、c){
**#预最大堆(l+1,u)
**#后最大堆(l,u)
**i=l
**而(1){
**#maxheap(l,u),除了我和它的孩子之间
**c=2*i#c=leftchild(i)
**如果(c>u)断裂;
**(c+xx[c])C++
**如果(x[i]>=x[c])中断
**互换(c,i)
**i=c
** }
** }
**
**功能hsort(i){
**#后排序(1,n)
**对于(i=int(n/2);i>=1;i--)
**siftdown(i,n)
**对于(i=n;i>=2;i--){
**互换(1,i)
**siftdown(1,i-1)
** }
** }
*/
在代码中,被排序的数组是x
,索引从1
到NN,不存在重复和重复!我不清楚if
和else
块中的计算应该做什么;它看起来不像是一个直接的交换。你检查ln
,你就会知道访问a[r]
时出现问题。如果数组大小为10(n==10
),且数组中的值为1000000及以上,则使用min=a[l];
或min=a[r];
意味着您将在一个本应比实际大得多的数组上递归。而拥有一个全局变量n
是很俗气的;请将它作为参数传递给函数。@JonathanLeffler:这些是交换(但不简单)。我建议使用临时的方法将它们更改为普通的旧交换。特别是因为min
已经作为临时存在。我同意它们是交换,但我会枪毙任何发送代码给我的人,让他们使用这么多不相关的操作来审查交换。这不仅晦涩难懂,而且是浪费。诚然,浪费是相对的,但。。。