hunterr986
hunterr986

Reputation: 43

Segmentation fault in C while using pointers

I don't know what's happening here:

#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");
}

The error is occurring right after the printf statement in the for loop and when I remove the * from the both the sides it works but the answer is wrong.

This is an insertion sort using pointers in C.

Upvotes: 2

Views: 746

Answers (4)

Chilledrat
Chilledrat

Reputation: 2605

The code below is close to your original, with the bug fixed, and a couple of tweaks for good measure. The main fix is replacing *k with key (which is pretty much what @pst and @SylvainL have already said.)

The reason, from the algorithm standpoint, is you need somewhere outside of array to hold the value being moved while the other array elements are shifted. Otherwise you end up overwriting array elements, which I suspect is what you found judging from the "...and when I remove the * from the both the sides it works but the answer is wrong." comment.

The Wikipedia entry on insertion sort has a nice animation that illustrates the point nicely:
enter image description here (image by Swfung8 CC BY-SA License page)

See code comments for other tweaks, as they aren't relevant to the question, just helpful pointers that you can take or leave ;-)

#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");
}

Upvotes: 0

SylvainL
SylvainL

Reputation: 3938

As stated by the others, part of your problem is that you are using an unitialized pointer to store a value. After reading your code, it appears that you are using *k simply to store an integer value and nothing else; therefore you don't need to have a pointer and using an ordinary int value should suffice:

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;
}

Furthermore, while *(ptr+i) represents the same thing as ptr[i], the usual C/C++ convention would be to use the later form.

Upvotes: 1

Kevin
Kevin

Reputation: 56049

You have declared k as a pointer but haven't given it any memory to point to, so there's no telling what will happen when you write to it. Give it some memory to write to with k = malloc(sizeof array).

Upvotes: 2

wallyk
wallyk

Reputation: 57764

The problem is, as you said, right after printf():

*k=*(ptr+j)

I didn't get as far as looking at the right side. The left side definitely has a problem: the pointer is not initialized, so writing to that address will almost certainly cause trouble.

The right side has a memory access too, but, after inspection it looks like it might be okay.

Upvotes: 5

Related Questions