0

I have an array that I created with malloc.

int *array = (int *) malloc(10 * sizeof(int));

I want to use this array in function.And I want to affect values of the array in main function. Like a pointer

void func(int **array);

How can I do this correctly?

First thing that comes to mind(working):

void func(int **arr){
    arr[0][0] = 100;
    arr[0][1] = 200;
}

int main(){
    int *arr = (int*) malloc(10 * sizeof(int));

    func(&arr);

    printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]);

    return 0;
}

Second(Not work):

typedef int* intarr;

void func(intarr *arr){
    *arr[0] = 100;
    *arr[1] = 200;
}
int main(){
    intarr arr = (int*) malloc(10 * sizeof(int));

    func(&arr);

    printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]);

    return 0;
}

My first question is why am I getting a segmentation error in the second method?

My second question is how accurate is the first method?

My third question is what are you using?

suiciyom
  • 21
  • 5
  • 1
    Re: second example. Although it is legal in C (and used incorrectly in the example) DO NOT typedef a name to be a pointer... Doing so makes code far less readable. The saying is: "experienced people want to see the splats"... Don't hide the fact that a name is actually a pointer (unless you really know what you are doing.) – Fe2O3 Oct 06 '22 at 22:50

2 Answers2

1

You only need to use **arr if the function needs to be able to reassign the caller's variable. See Changing address contained by pointer using function for examples where this is needed.

If it's just using and/or updating the contents of the array, just pass the pointer itself.

And if the function needs to know the size of the array, you'll need to pass that explicitly as well. See How to find the 'sizeof' (a pointer pointing to an array)?

void func(int *arr){
    arr[0] = 100;
    arr[1] = 200;
}

int main(){
    int *arr = malloc(10 * sizeof(int));

    func(arr);

    printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]);

    return 0;
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Or, use array notation in the function's parameter so that the reader doesn't have to "shift gears" mentally... Same thing, but simpler, imo... (Perhaps a mention that passing the the 'size' of the array is usually a good idea, too???) – Fe2O3 Oct 06 '22 at 22:52
  • True, although this transformation is so old and entrenched that beginners need to learn it and get used to seeing it. – Barmar Oct 06 '22 at 22:53
  • I am old and entrenched and still appreciate code that "flows" without little eddies or backcurrents... It is the same thing, but _smoother_... Cheers! (One could write the function block code with `*p++ = 100; *p++ = 200;` to be consistent...) – Fe2O3 Oct 06 '22 at 22:54
  • Re "*You only need to use **arr if the function needs to be able to reassign the caller's variable.*", e.g. if the call to `malloc` was in `func` (though you could just return the new pointer). – ikegami Oct 06 '22 at 23:23
  • @ikegami Right. And that's explained in detail in the question I linked to. I'm not going into detail here, because that's not what the question is about. – Barmar Oct 06 '22 at 23:29
  • @ikegami Odd that you don't raise the issue of `sizeof(int)` in this answer... Or uninitialsed variables from `malloc()`... Or the memory leak... Funny what some people are sensitive to, and what they are oblivious to... – Fe2O3 Oct 07 '22 at 00:01
-2

Then, there's this:

#include <stdio.h>

#if 1
// Showing the equivalent to "int *arr", array notation aids consistency
void func( int arr[], int sz ) {
    // Can test that array index does overrun size of array
    arr[0] = 100;
    arr[1] = 200;
}
#else
void func( int *arr, int sz ) {
    *(arr + 0) = 100;
    *(arr + 1) = 200;
}
#endif

int main() {
// EDIT - switch to calloc
//  int *arr = malloc( 10 * sizeof *arr ); // better. simple. don't cast.
    int *arr = calloc( 10, sizeof *arr ); // consistent initialisation
    /* omitting test for failure */

    func( arr, 10 ); // pass the size because function won't know.

    printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]);

    // No one has mentioned "memory leaks".
    // Amazing what qualifies as a "good" answer.

    free( arr );

    return 0;
}

People read code, too. Consideration for their ease is as important as getting the code right. (Bugs lurk in corners that are 'challenging'. Think about off-by-one mistakes.)

By using calloc(), the caller has assurance that array elements NOT set by the function will be consistent (ie. not changing from execution to execution as uninitialised variables can.) Consistent bad performance, if there are bugs, makes tracking down bugs much easier. Bugs that appear for some tests, then disappear for others, will cause the coder to age at an accelerated rate.

Fe2O3
  • 6,077
  • 2
  • 4
  • 20
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/248634/discussion-on-answer-by-fe2o3-a-pointer-of-array-as-function-parameter). – Dharman Oct 07 '22 at 13:56