2

I am programming in C. I send a structure as an argument to a function by "call by value method". Inside the function, I call another function which needs "call by reference" to the same structure. The call by value, should make a copy of structure and send a pointer of this copied version, to the inside function. My question is whether the original structure, outside both function will remain intact, no matter, how I play inside the functions.

Also, call by value, makes a copy of the structure. Is this very fast, compared to manually copying its member stuff, by using other algorithms like memcpy etc.

Example where function play changes the value

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

typedef struct{
    int dimension;
    double *vector;
}myVector;

void changeVec(myVector *X)
{
    X->vector[0]=100;
    X->vector[1]=200;
}

void foo(myVector X)
{
    changeVec(&X);
}

int main()
{
    myVector X;
    X.dimension=2;
    X.vector=malloc(sizeof(double)*X.dimension);
    X.vector[0]=1;
    X.vector[1]=2;
    printf("before function calling\n");
    for(int i=0; i<X.dimension; i++)
    {
        printf("%f ",X.vector[i]);
    }
    printf("\n");
    foo(X);
    printf("after function calling\n");
    for(int i=0; i<X.dimension; i++)
    {
        printf("%f ",X.vector[i]);
    }
    printf("\n");
    return 0;
}
user402940
  • 315
  • 2
  • 10

1 Answers1

1

Anything passed by value to a function remains "intact" as far as the caller is concerned. The reason is that the value passed is a COPY of the argument provided by the caller, and any changes to the COPY don't affect the original.

If the structure contains a pointer, the pointer can be dereferenced. Any changes made that way - to data that the pointer points at - WILL be visible to the caller. But the value of the pointer in the structure itself cannot be changed.

The compiler, when creating a copy of a structure, will generally pick the most efficient means of copying it. Your chances of beating that by copying members "by hand" are remote.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • Thanks. I just wrote a simple code myself to check it. It indeed changes the values of members inside structure. Can this be avoided ? I mean I have control over outer function but inner one is actually a BLAS library function which I can't change. Can we do this without making a deep copy manually to original structure and sending it. – user402940 Nov 14 '17 at 12:15
  • @user402940: if the library function mutates the data, then you either let it mutate your data, or create a deep copy and make it operate on a copy of the array. There isn't a third option. – vgru Nov 14 '17 at 13:16
  • If a data structure is passed by value, any change to the VALUES of members inside the function is not visible to the caller. If any member is a pointer, changing the value of the pointer itself (e.g. `passed_struct.pointer = malloc(42)`) is not visible to the caller. That assignment can be prevented by making the argument `const`. However, if you change a value by dereferencing that pointer (e.g. `passed_struct.pointer[0] = 42`) then that change IS visible to the caller. Unfortunately, there is no way - other than making the member `const` - to prevent such dereferencing. – Peter Nov 14 '17 at 14:13