Home > Net >  Global array won't update, keeps giving garbage values when passed by reference
Global array won't update, keeps giving garbage values when passed by reference

Time:04-08

It's supposed to call a function through a thread for merge sort- but for some reason, it doesn't update the global array when I try to output it later through the main() function. So i tried passing it by reference but that only made it give out random values instead, using int *array [] made it give positive random values instead of negative ones. I've been trying to figure out why it does that but currently have got nothing

Any clues on why it is behaving like this or how to update the global array would be appreciated.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int array[] = {3,4,6,2,6,8,2,9,3,1};

void merge(int array[], int l, int mid, int  r)
{
    printf("merge is running\n");   

    int size1 = r - mid;
    int size2 = mid- l 1;

    int left[size1];
    int right[size2];

    for(int i =0; i< size1; i  ){
        left[i] = array[l 1];
    }
    for(int j =0; j< size2; j  ){
        right[j] = array[mid   1  j];
    }
     
    int index1= 0; 
    int index2 = 0; 
    int index3 = l;

    while(index1 < size1 && index2< size2){
        if(left[index1] <= right[index2]){
        array[index3] = left[index1];
        index1  ;
        }
        else{
        array[index3] = right[index2];
        index2  ;
        }
        index3  ;
    }

    while(index1 < size1){
        array[index3] = left[index1];
        index1  ;
        index3  ;
    }

    while( index2< size2){
        array[index3] = right[index2];
        index2  ;
        index3  ;
    }
}

void MERGESORT(int array[], int start, int end)
{
    if(start<= end){
        printf("mergesort is finished\n");
        return;
    }

    int mid= start   (end - start)/2;
    MERGESORT(&array, start, mid);
    MERGESORT(&array, mid 1, end);
    merge(&array, start, mid, end);
}

void *thread_fun(void *arg)
{
    int oldstate, oldtype;
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
    printf("you are now in the thread\n");

    int start =0;
    int end = 10;
    MERGESORT(&array, start, end-1);
    printf("merge is done\n");
    printf("sorting finished\n");

    pthread_exit(NULL);
}

int main()
{
    printf("main is being executed\n");
    pthread_t tid1;
    char message[] = "this is a threadddd";
    pthread_attr_t threadat;
    pthread_attr_init(&threadat);
    pthread_attr_setdetachstate(&threadat, PTHREAD_CREATE_JOINABLE);

    pthread_create(&tid1, &threadat , thread_fun, (void*)message);
    pthread_attr_destroy(&threadat);
    int joinflag = pthread_join(tid1, NULL);

    if(joinflag==0){
        printf("join successful\n");
    }
    else
        printf("join failed\n");

    for(int i=0; i<10; i  ){
        printf("the array now contains: %d \n",&array[i]);

    }       
    pthread_exit(NULL);

    return 0;
}

CodePudding user response:

TL;DR Remove all the & in front of array and it should work.

An array is always passed by reference: think of the array as an int pointer. With an array declared like this int table[], using the variable table is exactly the same as using &table[0] -> The array variable directly points to its 1st element. The previous statement might sound weird, but you always modify the array itself when passing it to a function.

Using &array[i], you actually print the address of the i'th element, the same applies when calling the function MERGESORT().

CodePudding user response:

"Any clues on why it is behaving like this or how to update the global array would be appreciated."

When boiled down (beside dealing with the warnings and errors already mentioned, which will go a long way toward some of the unwanted behaviors.) the stated need is to address how to pass an array argument such that it can be updated by the function.

The following is not to address your function implementations. The comments have already pointed out that calling methods used in the example code for MERGESORT() are not compatible with its prototype, The following is stripped down to illustrate two simple functions, each taking an int array, and the number of elements in the array Each modifies the array and returns.

Note, the methods used to change array contents are not important, only that they do change the contents, and that the prototypes are able to convey the address of the array's modified memory block back to the caller.

Two methods:

int array[] = {3,4,6,2,6,8,2,9,3,1};

//qsort support
int compare (const void * a, const void * b) 
{
   return ( *(int*)a - *(int*)b );
}
//method 1 (passes pointer to address of first element of array, and count of elements)
void change_array(int *arr, int count)//note pointer argument
{                                     
    qsort(arr, count, sizeof(int), compare);
}
//method 2 (uses array notation argument, and loop assignments to modify)
void change_array_again (int count, int arr[])//note order of arguments
{
    for(int i=0;i<count;i  )
    {
        arr[i] = i 1;
    }
}

int main(void)
{
    int count = sizeof array/sizeof array[0];
    change_array(array, count); //using qsort
    change_array_again(count, array); //using hardcode assignments
    
    return 0;
}
  • Related