1

I am trying to build a function that gets (**group, *count) where count is the amount of items in the array and the group is a pointer to the array.

I must use **group instead of the much easier *group.

Edit: as requested ive included my main() func:

int *group1, **pgroup1, count1 = 0, *pcount1;
pgroup1 = &group1;
printf("please enter what size do you want the array to be..\n");
scanf("%d", &count1);
pcount1 = &count1;
BuildGroup(pgroup1, pcount1);

void  BuildGroup(int** group, int* count)
{
    int i = 0, j = 0, c = *count;
    group = (int**)malloc(c*sizeof(int**));
    if (group == NULL)
    {
        printf("ERROR: Out of memory\n");
        return 1;
    }
    printf("please enter the %d items in the array...\n", *count);
    for (i = 0; i < *count; i++) //going through the array items to be filled. 
    {
        scanf("%d", &group[i]);
        for (j = 0; j < i; j++)
        {
            while (group[i] == group[j]) //checking every item if he is already in the group,if he is in the group prompting the user for re-entering. 
            {
                printf("you've entered the same value as beforehand, please enter this value again..\n");
                scanf("%d", &group[j]);
            }
        }
    }
}

I don't know why but malloc doesn't allocate the memory needed for the array. On the other hand, it doesn't trigger the if (==null) so I really don't know what I am doing wrong.

Weak to Enuma Elish
  • 4,622
  • 3
  • 24
  • 36
Yochayt7
  • 21
  • 6
  • [Please see this discussion on why not to cast the return value of `malloc()` and family in `C`.](http://stackoverflow.com/q/605845/2173917). – Sourav Ghosh Apr 25 '16 at 08:25
  • 2
    It seems you have to become a [three-star programmer](http://c2.com/cgi/wiki?ThreeStarProgrammer). Search for and read about *emulating pass by reference in C*. Or, simply, *return* the allocated memory. – Some programmer dude Apr 25 '16 at 08:26
  • `scanf("%d", &group[i]);` are you sure? – Sourav Ghosh Apr 25 '16 at 08:26
  • VTC for unclear....(as of now).. – Sourav Ghosh Apr 25 '16 at 08:28
  • Or the issue might be something completely different, which is hard without knowing what `group` is supposed to be... Is it supposed to be an array of `int`, or an array of *arrays* of `int`? Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) to show us, including how you call this function. – Some programmer dude Apr 25 '16 at 08:29
  • @SouravGhosh again. this is something they are forcing us to do. i know all about the wrong doing of casting malloc. but they are actually downgrading us if we don't. – Yochayt7 Apr 25 '16 at 08:30
  • `*group = malloc(c*sizeof(int));`.. `scanf("%d", &(*group)[i]);` or `scanf("%d", *group + i);` .. `while ((*group)[i] == (*group)[j])` – BLUEPIXY Apr 25 '16 at 08:32
  • @JoachimPileborg you are correct(im fairly new to SO sorry about not showing an exemple) it is supposed to be an array of ints im supposed to send an empty pointer to pointer , this is how main looks like : int *group1, **pgroup1, count1 = 0, *pcount1; pgroup1 = &group1; printf("please enter what size do you want the array to be..\n"); scanf("%d", &count1); pcount1 = &count1; BuildGroup(pgroup1, pcount1); – Yochayt7 Apr 25 '16 at 08:33
  • BTW `return 1;` : return type is void. `scanf("%d", &group[j]);` --> `scanf("%d", &(*group)[i]);` – BLUEPIXY Apr 25 '16 at 08:36
  • 2
    @Yochayt7 Please don't post code in comments. [edit] your post and add the details there. – Sourav Ghosh Apr 25 '16 at 08:37

1 Answers1

4

It seems like what you are passing to the function (or really, should be passing to the function) is a pointer to a pointer variable, and then you should use the dereference in the function to access the pointer variable.

Something like this:

int *group;
int count = 10;
BuildGroup(&group, &count);

That means your function should look something like

void  BuildGroup(int **group, int *count)
{
    if ((*group = malloc(*count * sizeof(**group))) == NULL)
    {
        // Failed to allocate memory
        return;
    }

    printf("Please enter the %d items in the array...\n", *count);

    for (int i = 0; i < *count; ++i)
    {
        scanf("%d", *group + i);
        // `*group + i` is the same as `&(*group)[i]`

        ... inner loop here...
    }
}

I don't really see a reason for the count argument to be a pointer, unless the function is really supposed to set it too.


A little explanation about what's going on

In the main function you have a pointer variable, groups. You want to allocate memory and assign a pointer to that memory to the group variable. That's easy, that's just

group = malloc(N * sizeof(*group));

The problem comes because you want to allocate the memory inside another function, and it's a problem because when you pass an argument to a function it is done by value which means the value is copied and the argument variable inside the function is only a copy. Modifying a copy will of course not modify the original.

That problem could be solve if C could pass the group variable to the function by reference, meaning that inside the function the argument variable would reference the variable in the main function. Unfortunately C doesn't have pass by reference semantics, it only have pass by value. This can be solved by emulating pass by reference, by using pointers.

When you pass a pointer to a function, it is the pointer that is passed by value, and is copied, trying to change the pointer to point somewhere else is fruitless as it will only change the local copy of the pointer. However, we can change the data it points to, which is done using the dereference operator *. Passing a pointer to some data is done with the address-of operator &.

With the information above, how would one then emulate passing a pointer by reference? Just like any other variable, by using the address-of operator to pass a pointer to the pointer variable. Inside the function we then use the dereference operator to access to original pointer variable.

More graphically it could be seen something like this:

+--------------------------------+
| &group (in main function)      | -\
+--------------------------------+   \  +--------------------------+    +-----+
                                      > | group (in main function) | -> | ... |
+--------------------------------+   /  +--------------------------+    +-----+
| group (in BuildGroup function) | -/
+--------------------------------+
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • i dont understand why in main() group has only 1 star but in the func it has 2? it is because you gve it the address of the pointer rather than the pointer itself? oh and thank you very much for the quick help!! :) – Yochayt7 Apr 25 '16 at 08:48
  • i dont really understand whats going on here but it is working so i give you the 'answered' thanks!!! if you could help me understand it better i'll be very grateful :) – Yochayt7 Apr 25 '16 at 08:57
  • @Yochayt7 Updated answer with some explanatory text – Some programmer dude Apr 25 '16 at 09:19