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

char** mlc(char** f){
    int count=10;
    int size=10;
    f=(char**)malloc(count*sizeof(char*));
    for(int i=0;i<count;i++){
        f[i]=(char*)malloc(size*sizeof(char));
    }
    return f;
}
int main()
{
    char** f;
    f=mlc(f);
    f[0][0]='1';
    f[0][1]='\0';
    printf("%s",f[0]);
    return 0;
}

I use this code can work perfectly ,But when I use the following code ,It will get segmentation fault:

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

void mlc(char** f){
    int count=10;
    int size=10;
    f=(char**)malloc(count*sizeof(char*));
    for(int i=0;i<count;i++){
        f[i]=(char*)malloc(size*sizeof(char));
    }
    return f;
}
int main()
{
    char** f;
    mlc(f);
    f[0][0]='1';
    f[0][1]='\0';
    printf("%s",f[0]);
    return 0;
}

So ,the main difference is the first code I return the pointer, why the second code get fault?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Wei Xu
  • 19
  • 1
  • 2
    Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Jul 03 '15 at 12:09
  • 1
    @SouravGhosh you're the Barry Allen of no-casting-malloc :p – Quentin Jul 03 '15 at 12:21
  • "*... the first code I return the pointer, why the second code get fault?* because you do **not** "*return the [modified] pointer*". – alk Jul 03 '15 at 12:25
  • so (as answers are blocked), this might be bad programming style, but changing the `void` to `void*` and the line `mlc(f);` to `f=mlc(f);` fixes your problem (as @SouravGhosh pointed out, you do not assign the `f` back). – serv-inc Jul 03 '15 at 12:30
  • 1
    a few key things to note: 1) the posted code, in both examples, fails to cleanly compile. Suggest enabling all warnings when compiling and fixing those warnings. 2) 'sizeof(char)' is always 1, therefore has no effect on the call to malloc(). I.E. it just clutters the code. Suggest removing that expression. 3) always check (!=NULL) the returned value from malloc() to assure the operation was successful 4) compiler complains about uninitialized parameter to mlc(). Suggest eliminate that parameter, define the 'f' locally to the mlc function, – user3629249 Jul 03 '15 at 12:30
  • @user1587329: As the question linked shows the same problem as the second approach of this question, which the OP asks why it does not work. – alk Jul 03 '15 at 12:37
  • OT: The return statement (in `mlc()`) in the 2nd example it wrong. It shall not take an argument. – alk Jul 03 '15 at 12:38
  • @Quentin yep, seems so. :P – Sourav Ghosh Jul 03 '15 at 13:09

1 Answers1

3

In C, function arguments are passed by value. So, from inside the function, you cannot change the value of a parameter and expect the change to be reflected onto the variable passed in by the caller.

In simple words, in your case, from inside mlc(), you can change the value of *f, and that will be reflected onto the *f in main(), but you cannot change the value of f itself.

  • You first case works, because after allocating memory and pointing the parameter f at it, you return said pointer and retrieve it into f in main(). So, in main(), f is perfectly valid for usage.

  • Your second case fails, because after returning from the function, f in main() remains uninitialised.

Quentin
  • 62,093
  • 7
  • 131
  • 191
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261