C SegFault fixed by print?

Viewed 71

I have the task to write a program in C. The program should be able to check for parameters and create arrays that are as big as the parameter I gave. I have to fill the array with random numbers. Works fine so far. Later on my task is to sort the array using pointers. First thing is I did not quite understand how pointers work but I made the sorting work so far. The only problem is, that I can only sort to a size of 4. If my parameter is bigger than 4 I get the first 4 numbers sorted and then a Segmentation fault. I cannot find the issue but the fun part is, that if I add a printf just to print my parameter again it works fine for any parameter I want! I do not know what is happening!

Here is the exact task again, because I think I didn't describe it that well:

To do this, create a dynamic pointer field of the same size and initialize it with pointers to the elements of the int field. When sorting, the pointers should now be sorted so that the first pointer points to the smallest int value, the second to the next largest value, and so on.

int main(int argc, char *argv[]) {
    
    int *array;
    int **arrpointer;
    
    int size = atoi(argv[1]);
     
    if (size == 0) {
        fprintf(stderr, "Wrong parameter!\n");
        return EXIT_FAILURE;
    }

    //printf("Array-Size : ");   //First I had it with scanf, which works perfectly fine without a print
    //scanf("%d", &size);

    printf("Input%d", size);  //This is the print I need somehow!

    // allocate memory
    array = (int *)malloc(size * sizeof(int));        // Init Array
    arrpointer = (int **)malloc(size * sizeof(int));  // Init Pointer Array

    //Check Pointer array 
    if (arrpointer != NULL) {
        printf("Memory allocated\n\n");
    } else {
        fprintf(stderr, "\nNo free memory.\n");
        return EXIT_FAILURE;
    }
    
    if (array != NULL) {
        printf("Memory is allocated\n\n");

        //Fill Array
        for (int i = 0; i < size; i++) {
            array[i] = rand() % 1000; //I know it is not random right now, will add later
            int *temp = &array[i];
            arrpointer[i] = temp;     //Pointer fill
        } 
    } else {
        fprintf(stderr, "\nNo free memory to allocate.\n");
        return EXIT_FAILURE;
    }
    shakersort(arrpointer, size);  //Function to sort pointers
    zeigeFeld(arrpointer, size);  //Function to Print
        
    free(array);
    free(arrpointer);
    return EXIT_SUCCESS;
} 

I know its a bit confusing, I am sorry. I will also add the code where I sort it below.

void swap(int **a, int **b) {

    int ram;
    ram = **a;
    **a = **b;
    **b = ram;
}

void shakersort(int **a, int n) {
    int p, i;
    for (p = 1; p <= n / 2; p++) {
        for (i = p - 1; i < n - p; i++)
            if (*a[i] > *a[i+1]) {
                swap(&a[i], &a[i + 1]);
            }
           
        for (i = n - p - 1; i >= p; i--)
            if (*a[i] < *a[i-1]) {
                swap(&a[i], &a[i - 1]);                
            }           
    }
}

This is the code I tried to build for the pointers and it works fine so far.

I hope someone can help or give some input to why my print fixes the problem. I really dont understand! Thank you for your time and help, let me know if I should add anything!

3 Answers

The program has undefined behavior because the allocation size is incorrect for the array:

arrpointer = (int **)malloc(size * sizeof(int));

allocates space for size integers, but it should allocate space for size pointers to int, which on 64-bit systems are larger than int. Use this instead:

arrpointer = (int **)malloc(size * sizeof(int *));

Or use the type of the destination pointer:

arrpointer = malloc(sizeof(*arrpointer) * size);

This latter syntax is much safer as it works for any non void pointer type.

Note however that this array of pointers is overkill for your purpose. You should just implement the sorting functions on arrays of int:

void swap(int *a, int *b) {
    int ram = *a;
    *a = *b;
    *b = ram;
}

void shakersort(int *a, int n) {
    int p, i;
    for (p = 1; p <= n / 2; p++) {
        for (i = p - 1; i < n - p; i++) {
            if (a[i] > a[i + 1]) {
                swap(&a[i], &a[i + 1]);
            }
        }
        for (i = n - p - 1; i >= p; i--) {
            if (a[i] < a[i - 1]) {
                swap(&a[i], &a[i - 1]);                
            }
        }          
    }
}

Whether the above code actually sorts the array is unclear to me, I never use shakersort.

why do you use pointers before printf?? first you need to know what the pointer is: the pointer is some kind of variable that contains address of some another variable.

for example:

int b = 2;

int * a = &b;

a variable include the address of variable b. then if you print ((a)) it will give you hex number which is the address of b. if you print ((*a)), compiler will print what in the address that int the variable a and print the amount of number in address of cell b(that means 2).

now i guess you understand what the pointer is, look again at your code and correct the mistakes.

I updated my code from

arrpointer = (int **) malloc(size * sizeof(int));

to

arrpointer = malloc(sizeof *arrpointer * size);

And it works fine! Thank you all for your help!

Related