-4

My function prototype should look like this:

void double_min_max(int **range, int min, int max)

I have to fill 'range' with number from min to max.

I don't know how to malloc the double pointer and how to assign every element the number min.

void    double_min_max(int **range, int min, int max)
{
    range = (int **)malloc(sizeof(int)* 10);
    int i = 0;
        while (min < max)
        {
        **range[i] = min;
        i++;
        min++;
    }
}
nextdarius
  • 27
  • 1
  • 6
  • range = (int **) malloc(sizeof(max-min)); – Rajeshkumar Aug 16 '17 at 11:17
  • Nobody here will write the code for you. If you go to www.google.com and type in the title of your question, "malloc double pointer", there are plenty of examples regarding the allocation part. – Lundin Aug 16 '17 at 11:18
  • Then read how to use malloc and what a for loop is. @Rajeshkumar you this will allocate just the difference between min and max in bytes, also avoid casting the result from malloc. – Gnqz Aug 16 '17 at 11:19
  • What is your code so far, you should show your effort so that we can help you at a specific problem. – Andre Kampling Aug 16 '17 at 11:20
  • 2
    With this declaration, you should **pass** a pointer from calling code. Then just do `size_t size = max - min + 1; *range = malloc(size * sizeof **range);` –  Aug 16 '17 at 11:26
  • 1
    What's the use of the i variable and why *10? – Gnqz Aug 16 '17 at 11:29
  • 3
    like [this](http://ideone.com/iS0kDY) – BLUEPIXY Aug 16 '17 at 11:29
  • @AndreKampling surely. Added. – BLUEPIXY Aug 16 '17 at 11:34
  • In C, do not cast the result of a call to `malloc()`, `realloc()`, or `calloc()` - it is unnecessary and potentially masks the serious error of a missing prototype. – mlp Jul 15 '19 at 16:21

2 Answers2

4

Ok, let's spot the errors:

void double_min_max(int **range, int min, int max)
{
    range = (int **)malloc(sizeof(int)* 10);

The cast with malloc is unnecessary and could even lead to problems. Don't do this.

Then you want to assign to *range, not to range. range is local to your function (all arguments are passed by value in C), so modifying it will never have any effect visible to the calling code. When you call this function, you should pass a pointer to a pointer, so the pointer can be modified by the function through *range.

Finally, this should be obvious, but you should calculate the required size from your min and max. The 10 is just a ... uhm ... very rough guess. Not a good idea.

    int i = 0;
        while (min < max)
        {
        **range[i] = min;

This is wrong. [] does dereference the pointer, so you have three levels of dereferencing here. But it's only a pointer to pointer, not pointer to pointer to pointer. Also, indexing precedes the normal dereference, not what you want. Use (*range)[i] instead.

        i++;
        min++;
    }
}

A sensible implementation could look like this:

size_t double_min_max(int **range, int min, int max)
{
    // check for valid input
    if (min > max) return 0;

    // calculate required size
    size_t size = max - min + 1;

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

    // check allocation succeeded:
    if (!*range) return 0;

    for (size_t i = 0; i < size; ++i)
    {
        (*range)[i] = min++;
    }
    return size;
}

Call it like this:

int *range;
size_t result = double_min_max(&range, 10, 20);

// result should now be 11, the size of the array `range` points to

// when done:
free(range);
0

With **range = malloc..., you actually access/assign the first integer value to which the "pointer to pointer to int" (this is what int **range denotes) points. This should be *range = malloc... instead. Further, **range[i] is illegal, as **range is an integer value, not an array or pointer, such that the **range[i]=min dereferences an integer value (which in this context is illegal/undefined behaviour). It should rather be *range[i]=min.

So the complete code including some necessary checks, the use of the function and also the use of the result could look as follows:

int double_min_max(int **range, int min, int max) {

    // range is a pointer PPI to a pointer PI pointing to one (or more consecutive) integers I
    // *range is the "value" of PI, i.e. the pointer to the memory block representing the sequence of integers

    if (min >= max)  // check if the range is valid
        return 0;

    if (!range) // check if you may assign a value to *range
        return 0;

    int size = max - min;
    int *intArray = malloc(size * sizeof(int));
    if (!intArray) // did malloc fail?
        return 0;

    // fill the range
    for (int i=0; i<size; i++) {
        intArray[i] = min+i;
    }

    // let *range point to the malloced and filled array
    *range = intArray;

    // return the size of the array.
    return size;
}

int main() {

    int *myRange = NULL;
    int size = double_min_max(&myRange, -30, -10);

    if (size && myRange) {
        for (int i=0; i<size; i++) {
            printf("%d ", myRange[i]);
        }
        free(myRange);
    }
    return 0;
}
Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58