简体   繁体   中英

The pointers array returned from the function to the main is NULL

I was asked to create a function in C that gets an array of int's, its size and a character representing if the sort needs to be ascending or descending (0 for ascending, any other char if descending), and returns a pointers array. If the sort is ascending, the pointers will be sorted from minimum to maximum of the values in the int's array. Like that Everything works well until the pointers array is being returned to the main with a value of NULL. I mean, before the function ends and the array is being returned, there are values in the array (and they're also sorted well), but the moment the main gets the address from the function, it's null. Is anyone familiar with the problem?

Thank you!

#include <stdio.h>

#define SIZE 100

// Functions declaration
int** pointerSort(int* arr, unsigned int size, char ascend_flag);
void sortMerge (int** sortedArr, int left, int right, char ascend_flag);
void mergeSortAscend (int** arr, int left, int middle, int right);
void mergeSortDescend (int** arr, int left, int middle, int right);
void copyAddress(int** addressArray, int* arr, unsigned int size);

int main()
{
    int** sortedArr;
    int  arr[5] = {8,1,7,2,4};
    int size = 5;

    sortedArr = pointerSort(arr, size, '1');

    return 0;
}

// The pointerSort function gets an array, its size and a flag representing "sort by" (ascending, descending)
int** pointerSort(int* arr, unsigned int size, char ascend_flag)
{
    // Variables declaration
    int* sortedArr[size];

    // Copying the addresses of each value in arr to an addresses array
    copyAddress(sortedArr, arr, size);

    // Sending the array of addresses, its start and end and the ascend_flag to the sortMerge function
    sortMerge(sortedArr, 0, size - 1, ascend_flag);

    return (sortedArr);
}

void sortMerge (int** sortedArr, int left, int right, char ascend_flag)
{
    // Variables declaration
    int middle = (left + right) / 2;

    // Checking if there are more than one cell
    if (left < right)
    {
        // Splitting the array into two
        sortMerge(sortedArr, left, middle, ascend_flag);
        sortMerge(sortedArr, middle + 1, right, ascend_flag);

        // Checking if the sort requested is ascending or descending
        if (ascend_flag != '0')
        {
            mergeSortAscend(sortedArr, left, middle, right);
        }
        else
        {
            mergeSortDescend(sortedArr, left, middle, right);
        }
    }
}

void mergeSortAscend (int** arr, int left, int middle, int right)
{
    int l = left, m = middle + 1, r = right, i = left;
    int* temp[SIZE];

    while ((l <= middle) && (m <= right))
    {
        if (*(arr[l]) > *(arr[m]))
        {
            temp[i] = arr[m];
            m++;
        }
        else
        {
            temp[i] = arr[l];
            l++;
        }
        i++;
    }

    if (l <= middle)
    {
        while (l <= middle)
        {
            temp[i] = arr[l];
            l++;
            i++;
        }
    }

    if (m <= right)
    {
        while (m <= right)
        {
            temp[i] = arr[m];
            m++;
            i++;
        }
    }
    for (int k = left; k <= right; k++)
    {
        arr[k] = temp[k];
    }
}

void copyAddress(int** addressArray, int* arr, unsigned int size)
{
    int i;

    for (i = 0; i < size; i++)
    {
        addressArray[i] = &(arr[i]);
    }
}

void mergeSortDescend (int** arr, int left, int middle, int right)
{
    int l = left, m = middle + 1, r = right, i = left;
    int* temp[SIZE];

    while ((l <= middle) && (m <= right))
    {
        if (*(arr[l]) <= *(arr[m]))
        {
            temp[i] = arr[m];
            m++;
        }
        else
        {
            temp[i] = arr[l];
            l++;
        }
        i++;
    }

    if (l <= middle)
    {
        while (l <= middle)
        {
            temp[i] = arr[l];
            l++;
            i++;
        }
    }
    if (m <= right)
    {
        while (m <= right)
        {
            temp[i] = arr[m];
            m++;
            i++;
        }
    }
    for (int k = left; k <= right; k++)
    {
        arr[k] = temp[k];
    }
}

The int* sortedArr[size]; in int** pointerSort(int* arr, unsigned int size, char ascend_flag) becomes invalid as soon your function returns since it is an automatic variable allocated of the stack.

You need a permanent storage. For example allocate memory for sortedArr on the heap by the malloc function and return it.

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

#define SIZE 100

// Functions declaration
int** pointerSort(int* arr, unsigned int size, char ascend_flag);
void sortMerge (int** sortedArr, int left, int right, char ascend_flag);
void mergeSortAscend (int** arr, int left, int middle, int right);
void mergeSortDescend (int** arr, int left, int middle, int right);
void copyAddress(int** addressArray, int* arr, unsigned int size);

int main(void)
{
    int** sortedArr;
    int  arr[5] = {8,1,7,2,4};
    int size = 5;
    int i =0;

    sortedArr = pointerSort(arr, size, '1');

    if(sortedArr) // memory was allocated
       for(i=0; i<5; i++){
           printf("%d ", *sortedArr[i]);
       }

    free(sortedArr);
    return 0;
}

// The pointerSort function gets an array, its size and a flag representing "sort by" (ascending, descending)
int** pointerSort(int* arr, unsigned int size, char ascend_flag)
{
    // Variables declaration
    //int* sortedArr[size];
    int ** sortedArr = malloc( sizeof(int *) * size);
    if(sortedArr == NULL) return NULL; // no memory

    // Copying the addresses of each value in arr to an addresses array
    copyAddress(sortedArr, arr, size);

    // Sending the array of addresses, its start and end and the ascend_flag to the sortMerge function
    sortMerge(sortedArr, 0, size - 1, ascend_flag);

    return (sortedArr);
}

void sortMerge (int** sortedArr, int left, int right, char ascend_flag)
{
    // Variables declaration
    int middle = (left + right) / 2;

    // Checking if there are more than one cell
    if (left < right)
    {
        // Splitting the array into two
        sortMerge(sortedArr, left, middle, ascend_flag);
        sortMerge(sortedArr, middle + 1, right, ascend_flag);

        // Checking if the sort requested is ascending or descending
        if (ascend_flag != '0')
        {
            mergeSortAscend(sortedArr, left, middle, right);
        }
        else
        {
            mergeSortDescend(sortedArr, left, middle, right);
        }
    }
}

void mergeSortAscend (int** arr, int left, int middle, int right)
{
    int l = left, m = middle + 1, r = right, i = left;
    int* temp[SIZE];

    while ((l <= middle) && (m <= right))
    {
        if (*(arr[l]) > *(arr[m]))
        {
            temp[i] = arr[m];
            m++;
        }
        else
        {
            temp[i] = arr[l];
            l++;
        }
        i++;
    }

    if (l <= middle)
    {
        while (l <= middle)
        {
            temp[i] = arr[l];
            l++;
            i++;
        }
    }

    if (m <= right)
    {
        while (m <= right)
        {
            temp[i] = arr[m];
            m++;
            i++;
        }
    }
    for (int k = left; k <= right; k++)
    {
        arr[k] = temp[k];
    }
}

void copyAddress(int** addressArray, int* arr, unsigned int size)
{
    int i;

    for (i = 0; i < size; i++)
    {
        addressArray[i] = &(arr[i]);
    }
}

void mergeSortDescend (int** arr, int left, int middle, int right)
{
    int l = left, m = middle + 1, r = right, i = left;
    int* temp[SIZE];

    while ((l <= middle) && (m <= right))
    {
        if (*(arr[l]) <= *(arr[m]))
        {
            temp[i] = arr[m];
            m++;
        }
        else
        {
            temp[i] = arr[l];
            l++;
        }
        i++;
    }

    if (l <= middle)
    {
        while (l <= middle)
        {
            temp[i] = arr[l];
            l++;
            i++;
        }
    }

    if (m <= right)
    {
        while (m <= right)
        {
            temp[i] = arr[m];
            m++;
            i++;
        }
    }

    for (int k = left; k <= right; k++)
    {
        arr[k] = temp[k];
    }
}

Test:

1 2 4 7 8 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM