-1

pals. I found that the return value of fopen is different by the following two ways:

1.
int main()
{
    FILE* fp_file = NULL;
    fp_file = fopen(file_path, "wb"); 
    if(NULL == fp_file) 
      return RET_NULL_POINT; 
    else
      return RET_OK;
}

2.
int _open_file(const char* ps_file_path, const char* ps_open_mode, FILE* fp_arg)
{
    if(NULL == ps_file_path || NULL == ps_open_mode)
    { return RET_INV_ARG;}

    fp_arg = fopen(ps_file_path, ps_open_mode); 
    if(NULL == fp_arg)
    { return RET_NULL_POINT;} 
    else
    { return RET_OK;}// fp_arg is NULL after fopen, but it return RET_OK, why?
}

int main()
{
    FILE* fp_file = NULL;
    int i4_ret = 0;

    i4_ret = _open_file((const char*)file_path, "wb", fp_file);
    if(RET_OK != i4_ret)
    {// do sth NG}
    else
    {// do sth OK}

    ......//NULL_POINT exception will be caused at some place below.
}

The file_path of 2) is same to 1). The result of 1) is return RET_OK, the result of i4_ret of 2) is RET_OK, but fp_file is NULL. I want to know why the fp_file of 1) is correct value, but in 2) it's NULL? There is no difference of arguments of fopen between 1) and 2).

Lance.Koo
  • 11
  • 3
  • 2
    Duplicate hundreds of times over. C is a pass-by-value language. – Carl Norum Jul 09 '13 at 14:49
  • possible duplicate of ["Initializing" the pointer in the separate function in C](http://stackoverflow.com/questions/2486235/initializing-the-pointer-in-the-separate-function-in-c) – Carl Norum Jul 09 '13 at 14:50

4 Answers4

3

This is because params passed to a function are copied (in this case the pointer is copied). So when you call:

_open_file((const char*)file_path, "wb", fp_file);

The function _open_file is getting a copy of the pointer fp_file, thus the copy of the pointer is updated in the invoked function, but not the pointer in main .

See this thread to have more information about passing variables by value and by reference.

Community
  • 1
  • 1
Ottavio Campana
  • 4,088
  • 5
  • 31
  • 58
0
FILE* fp_file = NULL;
...
i4_ret = _open_file((const char*)file_path, "wb", fp_file);
             ...
             fp_arg = fopen(ps_file_path, ps_open_mode);

The fp_file reference is considered as being sent as a value to the function _open_file. Even if you try to modify the reference fp_file in the _open_file function, the change won't hold after you leave the function.

Even if you send a pointer as a parameter to your function, in that function you don't modify the content of the memory area pointed through that reference, you modify the reference itself. This is copied as a local variable in the _open_file function and changed only locally.

In order to be able to modify the reference you have to send as argument to your function a reference to your FILE reference.

FILE* fp_file = NULL;
...
i4_ret = _open_file((const char*)file_path, "wb", &fp_file);
             ...
             *fp_arg = fopen(ps_file_path, ps_open_mode); 
ionela.voinescu
  • 384
  • 1
  • 7
0

You have a FILE* named fp_file in your main() function. When you call _open_file(), this pointer is passed as a parameter and stored in a local variable fp_arg in the function.

The function then modifies this fp_arg variable to contain the new pointer returned by fopen().

The fp_file in main() isn't affected by these changes to the fp_arg variable. When the _open_file() returns, fp_file still is in the same state that it started in.

sth
  • 222,467
  • 53
  • 283
  • 367
0

Well _open_file() works correctly but fp_arg = fopen(...) assigns another pointer to your argument variable fp_arg and that is not passed back. It's the same as if yout passed an int to a function and changed it there. Change the signatuer of _open_file() to

int _open_file(const char* ps_file_path, const char* ps_open_mode, FILE** fp_arg)

set the value of fp_arg by

*fp_arg = fopen()

and call

i4_ret = _open_file((const char*)file_path, "wb", &fp_file);
Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33