简体   繁体   中英

Initialization and increment of array of pointers to integers

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.

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);    
}

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;
}

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);
}

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