1

I have written the following code in C for initializing and increment an array of pointers to int.

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

int * arr;

void initArray (int *arr, int size) {
    arr = malloc(sizeof(int)*size);
    for (int i=0; i< size; i++) {
        arr[i]= i;
        printf("%d ", arr[i]);
    }
    printf("\n");
} 

void incArray(int *arr, int size) {
    for (int i=0; i< size; i++) {
        arr[i]= i+1;
        printf("%d ", arr[i]);
    }
    printf("\n");
} 


void main(){

    initArray(arr, 3);
    incArray(arr, 3);

}

Unless I use malloc in both functions, the program (when run) gives this error:

Running "/home/ubuntu/workspace/hello-c-world.c"
0 1 2
bash: line 12: 93714 Segmentation fault "$file.o" $args
Process exited with code: 139

Not sure why once the initArray function is called why it needs memory allocation again in increment function. I am assuming it's treating the array for the second function as a separate one whereas I want to increment the values in the first array that initArray function creates.

I'd really appreciate being pointed in the right direction.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 3
    The `arr` in `initArray()` is hiding the global `arr`, and modifications made to `arr` in `initArray()` are not made to the global `arr`. Your code then calls `incArray()` with the (unmodified) global `arr` — which is still a null pointer. This gives you a seg fault when you try to use it. You'll need to work out whether you want the global variable or not — I suggest removing it. In that case, you change `initArray()` to have the signature `int *initArray(int size);` and you call it as `int *arr = initArray(3);`. There are other changes to make too, of course. – Jonathan Leffler Apr 08 '16 at 20:54
  • If you're running on Ubuntu as the errors suggest, then `void main()` is unconditionally incorrect and GCC will be complaining about it (or, if it isn't, you aren't using the correct warning options — start with `-Wall`). See [What should `main()` return in C and C++](http://stackoverflow.com/questions/204476/) for the details. – Jonathan Leffler Apr 08 '16 at 20:58
  • 2
    There is no array of pointers in your code. – too honest for this site Apr 08 '16 at 20:59
  • `arr` is an array of pointers, and you allocating an array of `int`. Change to `malloc(sizeof(int *) * size)`. Also, you're not really incrementing the values in the array, you're just assuming they are 0..N-1 and replacing them with 1..N. – Lee Daniel Crocker Apr 08 '16 at 22:25
  • This is my first ever program in c and I am using c9.io for coding right now but would like to start using an offline compiler soon.@Olaf How I understood this was "int *arr " refers to an array of pointer to integers and "malloc" initializes the array, let me know what is the right way to represent an array of pointers to integers – Sundas Waheed Apr 09 '16 at 10:01

3 Answers3

2

You want this:

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

void initArray (int **arr, int size) {
    *arr = malloc(sizeof(int)*size);
    for (int i=0; i< size; i++) {
        (*arr)[i]= i;
        printf("%d ", (*arr)[i]);
    }
    printf("\n");
} 

void incArray(int *arr, int size) {
    for (int i=0; i< size; i++) {
        arr[i]= i+1;
        printf("%d ", arr[i]);
    }
    printf("\n");
} 


void main(){  
    int *arr;  

    initArray(&arr, 3);  // << this will modify arr
    incArray(arr, 3);    
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
0

The arr in initArray() is hiding the global arr, and modifications made to arr in initArray() are not made to the global arr. Your code then calls incArray() with the (unmodified) global arr — which is still a null pointer. This gives you a seg fault when you try to use it. It also means that you leak the memory when the function returns.

You'll need to work out whether you want the global variable or not — I suggest removing it. Global variables should be avoided when possible.

You will need to change the signature of the initArray() function — there are (at least) two options.

Option 1 — Return pointer to allocated space

You could change initArray() to return a pointer to the allocated space. It would have the signature int *initArray(int size) and you'd call it as:

int *arr = initArray(3);

This yields:

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

int *initArray(int size)
{
    int *arr = malloc(sizeof(int)*size);
    if (arr != 0)
    {
        for (int i = 0; i < size; i++)
        {
            arr[i] = i;
            printf("%d ", arr[i]);
        }
        printf("\n");
    }
    return arr;
}

void incArray(int *arr, int size)  // Unchanged
{
    for (int i = 0; i < size; i++)
    {
        arr[i] = i+1;
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main(void)
{
    int *arr = initArray(3);
    if (arr != 0)
        incArray(arr, 3);
    return 0;
}

Where I compare to 0, you may prefer to compare to NULL. Note that the code is careful to check that allocations succeed before using the allocated space.

Option 2 — Pass a pointer to a pointer

Alternatively, if you like double pointers, you can pass a pointer to a pointer to the function:

void initArray(int **arr, int size)
{
    *arr = malloc(sizeof(int) * size);
    if (*arr != 0)
    {
        for (int i = 0; i < size; i++)
        {
            (*arr)[i] = i;
            printf("%d ", (*arr)[i]);
        }
        printf("\n");
    }
}

// incArray unchanged again

int main(void)
{
    int *arr;
    initArray(&arr, 3);
    if (arr != 0)
        incArray(arr, 3);
    return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
0

In your code, you have two variables whose name is arr : one is inside the global scope, and the other one is in initArray function scope. Look at this instruction inside initArray :

arr = malloc(sizeof(int)*size);

As function's local scope is resolved before global's one in C language, it's the arr parameter of the function which is going to store the allocation, not the global arr variable. And as you're returning nothing, this pointer will be destroyed at the end of your function, and you will not have any access to your allocation anymore. And so, the global arr will never be modified and its value will always be NULL or an undefined value.

This is why, inside incArray when you're doing this writing instruction...

arr[i]= i+1;

... you are actually trying to write i + 1 in a NULL or undefined address, which is not an address your processus has the right to write in, causing this segmentation fault.

A simple fix would be to return the pointer in initArray and to store it in your global arr variable, like that:

int * arr;

int* initArray (int size) {
    int* arr = malloc(sizeof(int)*size);
    // ...
    return arr;
} 

void incArray(int *arr, int size) {
    // ...
} 


void main(){
    arr = initArray(3);
    incArray(arr, 3);
}
Brim
  • 11