使用指针时C中的分段错误

时间:2012-06-15 00:15:24

标签: c pointers

我不知道这里发生了什么:

#include<stdio.h>
int main() 
{
    int i, j, *k, x,array[]={5,3,4,1,8,9,2,7,6,0};
    int *ptr=array;

    for(j=1;j<10;j++) {
        printf("---------iteration %d--------------\n",j);
        *k=*(ptr+j);   // the segmentation error is occurring here at this line
        printf("key=%d\n",*k);
        i=j-1;

        while( i>=0 && *k < *(ptr+i)) {
            *(ptr+i+1)=*(ptr+i);
            i--;
        }

        *(ptr+i+1) = *k;
        printf("%d\n",*(ptr+i+1));

        for( x=0;x<10;x++)
            printf("%d,",*(ptr+x));

        printf("\n");
    }

    for( i=0;i<10;i++)
        printf("%d,",*ptr++);

    printf("\n");
}

错误发生在printf循环中的for语句之后,当我从它的两侧移除*时,但答案是错误的。

这是使用C中的指针的插入排序。

4 个答案:

答案 0 :(得分:5)

正如你所说,问题就在printf()之后:

*k=*(ptr+j)

我没有看到正确的一面。左边肯定有一个问题:指针没有初始化,所以写入该地址几乎肯定会造成麻烦。

右侧也有内存访问权限,但经过检查后看起来可能没问题。

答案 1 :(得分:2)

您已将k声明为指针,但未指出任何指向内存的内容,因此无法确定写入时会发生什么。给它写一些内存来写k = malloc(sizeof array)

答案 2 :(得分:1)

正如其他人所说,你的部分问题是你正在使用一个整体指针来存储一个值。在阅读完代码后,您似乎只是使用* k来存储整数值而不是其他内容;因此,您不需要指针,并且使用普通的int值就足够了:

int i, j, k, x,array[]={5,3,4,1,8,9,2,7,6,0}; 
int *ptr=array; 

for(j=1;j<10;j++) { 
    printf("---------iteration %d--------------\n",j); 
    k=*(ptr+j);   // the segmentation error is occurring here at this line 
    printf("key=%d\n",k); 
    i=j-1; 

    while( i>=0 && k < *(ptr+i)) { 
        *(ptr+i+1)=*(ptr+i); 
        i--; 
    } 

    *(ptr+i+1) = k;
}

此外,虽然*(ptr + i)代表与ptr [i]相同的东西,但通常的C / C ++惯例是使用后面的形式。

答案 3 :(得分:0)

下面的代码接近您的原始代码,并修复了错误,并进行了一些调整以获得良好的衡量标准。主要修复方法是将*k替换为key(这正是@pst和@SylvainL已经说过的。)

从算法的角度来看,原因是你需要在array之外的某个位置保持移动的值,同时移动其他array元素。否则你最终会覆盖array元素,我怀疑这是你从中判断出来的......当我从它的两侧移除*但它的答案是错了。“评论。

Wikipedia entry on insertion sort有一个很好的动画,很好地说明了这一点:
enter image description here (图片来自Swfung8 CC BY-SA License page

查看其他调整的代码注释,因为它们与问题无关,只是您可以带走或离开的有用指示;-)

#include<stdio.h>

int main() 
{
    int array[]={5,3,4,1,8,9,2,7,6,0};

    int elm, key, i;
    int *ptr=array;

    // Calculate the number of array elements so the code will still 
    // work if the data set changes.  A good habit, rather than a necessity 
    // in this code, but it is used in two places... ;-) .

    int array_len = sizeof(array) / sizeof(int);

    for(elm=1; elm < array_len; elm++) {
        printf("---------iteration %d--------------\n",elm);
        key=(ptr+elm);
        printf("key=%d\n", key);

        // The while loop here was a for loop in disgise.

        for ( i=elm-1; i >= 0 && key < *(ptr+i); i-- ) {
            *(ptr+i+1) = *(ptr+i);
        }

        *(ptr+i+1) = key;
        printf("%d\n",*(ptr+i+1));

        // x declaration moved to here as it is only used as a loop counter

        for(int x=0; x < array_len; x++)
            printf("%d,",*(ptr+x));

        printf("\n");
    }

    for( i=0; i < 10; i++)
        printf("%d,",*ptr++);

    printf("\n");
}