Search code examples
cmallocdynamic-memory-allocationpass-by-valuefunction-definition

Get segmentation fault when manipulating with malloc in c


I am implementing a program to divide all value in a array by 100 then store them in b array using malloc. The problem is I got segmentation fault when printing value of b in main.

This is my code

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

void divide(int *a, int n, double *b){
    b=malloc(n*sizeof(double));
    
    for(int i=0; i<n; i++){
        b[i]=(double)a[i]/100.0;
    }

    //check: values still remain in b
    for (size_t i = 0; i < 5; i++)
    {
        printf("%.2f ", b[i]);
    }
}

int main(){
    int a[]={1,2,3,4,5};
    double *b;

    divide(a,5,b);
    
    //check: lost value and cause segmentation fault
    for (size_t i = 0; i < 5; i++)
    {
        printf("%.2f ", b[i]);
    }
    free(b);
    return 0;
}

So what cause this problem and how to fix it?

Thanks in advance.


Solution

  • You are passing the pointer b by value to the function divide

    divide(a,5,b);
    

    That is the function deals with a copy of the original pointer. Changing the copy does not influence on the original pointer.

    You need either to pass the pointer by reference through a pointer to it or redesign the function such a way that it will return a pointer to the dynamically allocated memory within the function.

    For example the function could be declared and defined the following way

    double * divide( const int *a, size_t n )
    {
        double *b = malloc( n * sizeof( double ) );
    
        if ( b != NULL )
        {
            for ( size_t i = 0; i < n; i++ )
            {
                b[i] = a[i] / 100.0;
            }
    
            //check: values still remain in b
            for ( size_t i = 0; i < n; i++ )
            {
                printf("%.2f ", b[i]);
            }
        }
    
        return b;
    }
    

    And in main you can write

    double *b = divide( a, sizeof( a ) / sizeof( *a ) );
    

    Otherwise the function can look like

    void divide( const int *a, size_t n, double **b )
    {
        *b = malloc( n * sizeof( double ) );
    
        if ( *b != NULL )
        {
            for ( size_t i = 0; i < n; i++ )
            {
                ( *b )[i] = a[i] / 100.0;
            }
    
            //check: values still remain in b
            for ( size_t i = 0; i < n; i++ )
            {
                printf("%.2f ", ( *b )[i]);
            }
        }
    }
    

    And called like

    divide( a, sizeof( a ) / sizeof( *a ), &b );