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;

我只是简单地用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;

    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
N

N,不存在重复和重复!我不清楚
if
else
块中的计算应该做什么;它看起来不像是一个直接的交换。你检查
ln
,你就会知道访问
a[r]
时出现问题。如果数组大小为10(
n==10
),且数组中的值为1000000及以上,则使用
min=a[l];
min=a[r];
意味着您将在一个本应比实际大得多的数组上递归。而拥有一个全局变量
n
是很俗气的;请将它作为参数传递给函数。@JonathanLeffler:这些是交换(但不简单)。我建议使用临时的方法将它们更改为普通的旧交换。特别是因为
min
已经作为临时存在。我同意它们是交换,但我会枪毙任何发送代码给我的人,让他们使用这么多不相关的操作来审查交换。这不仅晦涩难懂,而且是浪费。诚然,浪费是相对的,但。。。