0

Why my way is doesnt work? "message" refers to Null

first function :

void messageToBit(FILE *m,char *message )
{
    int fileSize = 0;
    int k = 0;
    char symb;
    fseek(m, 0, SEEK_END);
    fileSize = ftell(m);
    fseek(m, 0, SEEK_SET);
    message = (char*)malloc(8 * fileSize);
    /* some action with message */

}

and call

void gg()
{
 char* message = 0;

    messageToBit(m, message);
....
}

why not pointing to the correct memory location?

Caleb Bell
  • 520
  • 6
  • 23
tproger
  • 77
  • 7
  • Note: `int fileSize` should be `long`, the return type of `ftell()`. – chux - Reinstate Monica Mar 11 '16 at 18:45
  • How to *return* you ask? Well, by actually *returning* the data. Or search for *emulating pass by reference in c*. – Some programmer dude Mar 11 '16 at 18:46
  • Thou shan't cast result of `malloc`! – SergeyA Mar 11 '16 at 18:59
  • @SergeyA Thou shalt not recite obsolete C programming slogans. Thou shalt operate your compiler such that it diagnoses calls to functions that have not been previously introduced by prototype declarations, so that a call to `malloc` with no `` is diagnosed whether or not there is a cast. – Kaz Mar 11 '16 at 19:26
  • @Kaz, why type extra and increase noise to signal ratio of your code? Even if compiler warns you of implict function declaration. – SergeyA Mar 11 '16 at 19:46
  • @SergeyA One reason is portability to C++. (E.g. coding in "Clean C" that builds as C++). Another one is that you need some redundant information to catch errors. For instance `obj->buf = (char *) malloc(BUFFER_SIZE);` If `buf` changes to some other type, there will be a helpful conversion diagnostic. If we drop the `(char *)`, we lose the check, and can add something else to try to prevent the problem, like: `obj->buf = malloc(BUFFER_SIZE * sizeof *obj->buf)`. – Kaz Mar 11 '16 at 22:26

2 Answers2

1

You need to understand, pass-by-value and pass-by-reference. Change the code to

first function :

void messageToBit(FILE *m,char **message )
{
    int fileSize = 0;
    int k = 0;
    char symb;
    fseek(m, 0, SEEK_END);
    fileSize = ftell(m);
    fseek(m, 0, SEEK_SET);
    *message = (char*)malloc(8 * fileSize);
    /* some action with message */

}

and call

void gg()
{
 char* message = 0;

    messageToBit(m, &message);
....
}
Haris
  • 12,120
  • 6
  • 43
  • 70
  • for (int j = 128; j > 0; j /= 2) { if (symb&j) message[k] = 1; else message[k] = 0; } How fix these lines? if i pass * like this for (int j = 128; j > 0; j /= 2) { if (symb&j) *message[k] = 1; else *message[k] = 0; } i get the error – tproger Mar 11 '16 at 19:15
  • @tproger, If thats a different question, then please post it separately. – Haris Mar 11 '16 at 19:17
1

The point is that you should pass a pointer to pointer as a parameter in order to get output value this way. It might be confusing for beginners so instead you can achieve the same result by returning a pointer:

char* messageToBit(FILE *m)
{
    int fileSize = 0;
    int k = 0;
    char* message;
    char symb;
    fseek(m, 0, SEEK_END);
    fileSize = ftell(m);
    fseek(m, 0, SEEK_SET);
    message = malloc(8 * fileSize); // as mentioned in comments, no cast
    /* some action with message */
    return message;
}

void gg()
{
 char* message = messageToBit(m);
....
}
bottaio
  • 4,963
  • 3
  • 19
  • 43
  • thanks:) but could you explain why you need a pointer to a pointer? after all, when working with arrays is usually used just a pointer to transmit – tproger Mar 11 '16 at 18:42
  • If you pass char* message and assign a new value to it you have no effect on the message pointer from gg function. It is an analogy to passing int and int* as a parameter. If you pass int x to a function and assign new value to in inside say x = 5 then this result is not seen outside this function. When you pass int* x and do the assignment as *x = 5 then you are actually modifying the value of x which address in memory was passed. That's why you should pass char** message and assign to it in this manner: *message = ... – bottaio Mar 11 '16 at 18:47
  • When you pass int* x and do the assignment as x = 5 then you are actually modifying the value of x which address in memory was passed. -I know this, and so I pass char* message : void messageToBit(FILE *m,char *message ) – tproger Mar 11 '16 at 18:58
  • Do not cast result of `malloc`. – SergeyA Mar 11 '16 at 19:00
  • @tproger note that you are not trying to modify a char! now you want to modify array of chars (char*). That's why the type should be char** – bottaio Mar 11 '16 at 19:15
  • @SergeyA what about malloс?can you explain, please? – tproger Mar 11 '16 at 19:32
  • @tproger There is an excellent post on SO about casting malloc result, you can easily find it. http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – bottaio Mar 11 '16 at 19:34