1

I am a newbie in C.

I know this is correct:

char* Str;
Str = (char*)calloc(Str_Len, sizeof(char));

, but why this is not correct?

char* Str;
*Str = (char*)calloc(Str_Len, sizeof(char));

How to modify it? Thanks.

Kevin Dong
  • 5,001
  • 9
  • 29
  • 62
  • 2
    Because `calloc` returns a pointer, and you're trying to assign it to a `char`. Also, you [shouldn't](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) be casting the return value. – Praetorian Jan 06 '14 at 19:06
  • 1
    "How to modify it?" -- The answer to that seems fairly obvious. You know the first snippet is correct and the second one isn't. So use the first. But an even better way to write it is `char *Str = calloc(Str_Len, sizeof *Str);`. For that matter, you *probably* don't need to zero more than the first byte, so: `char *Str = malloc(Str_Len); Str[0] = '\0';` (`sizeof (char)` is 1 by definition) – Keith Thompson Jan 06 '14 at 19:35

3 Answers3

1

First is legal, but do not cast the return value of malloc or calloc in C (as their return type is void *).
In second case Str is char type, you can't allocate memory more thatn 1 byte to it. Also calloc returns pointer but *Str is of type char. You can't assign a char * data type to char type.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
1

Actually none of both is correct, since there is no need to cast a void* in C to anther type, it's implicitly convertible. The cast is not an error per se but it could led to hidden errors.

The latter is wrong because *Str dereferences the pointer (thus you access the char) which is not a pointer type and it's not assignable from a pointer.

Jack
  • 131,802
  • 30
  • 241
  • 343
  • 1
    Casting calloc is correct and valid code in the first case. If something is by someone considered bad practice it doesn't mean it is not correct when talking about a language defined by specific rules. – this Jan 06 '14 at 19:09
  • 1
    @self. - Correct and valid, but also stylistically abhorrent. What do you think this is, C++? – asveikau Jan 06 '14 at 19:10
  • @asveikau not correct != stylistically abhorrent. Please don't be misleading. – this Jan 06 '14 at 19:11
  • 1
    @self: an unnecessary cast force the compiler to ignore type checking, so it's not just aesthetically bad. – Jack Jan 06 '14 at 19:16
  • 1
    @Jack It is actually the opposite. Adding the cast will warn you if you change you variable type if you use sizeof( type ) in malloc. Leaving cast is only ok if you use sizeof( *var ). – this Jan 06 '14 at 19:21
  • 1
    @self: Under C89, casting the result of `*alloc` can suppress a useful diagnostic if you forget to include `stdlib.h` or otherwise not have a declaration for the function in scope, leading to runtime errors. Yes, `C99` got rid of implicit declarations, so that's not as much a danger anymore, but it is still considered bad practice. After all, up until this last standard revision, `gets` is correct and valid, even though its use is *guaranteed* to create a point of failure in your code. – John Bode Jan 06 '14 at 19:21
  • 1
    @JohnBode The argument of forgetting to include the *Standard Library* is very weak. Yes, as I said, not casting sizeof(*var) is ok. In the other case( see my comment ) it is not. – this Jan 06 '14 at 19:24
  • 2
    @self - I saw your other comment, and it makes no sense. Are you saying you'll get a diagnostic on `char *x = (char *) malloc( sizeof (int));`? – John Bode Jan 06 '14 at 19:26
  • 1
    @JohnBode No you get it on: `int *x = (char *) malloc( sizeof (char));` if you change the type of variable. With int *x = malloc( sizeof (char));` you don't. – this Jan 06 '14 at 19:29
  • @self. - I never claimed stylistically abhorrent was incorrect. Please re-read the comment. – asveikau Jan 06 '14 at 19:30
  • 2
    @self: Which is why the recommended practice is to write `T *p = malloc( sizeof *p * N );`. No need to worry about keeping all your types straight. No matter what you change `T` to, you'll always get the right amount of memory allocated. – John Bode Jan 06 '14 at 19:32
  • @JohnBode Yes, that is why i said *using sizeof(*var)* you don't have to cast. Reading is tech. – this Jan 06 '14 at 19:33
0

Neither

char* Str;
Str = calloc(Str_Len, sizeof(char));

Is correct

Ed Heal
  • 59,252
  • 17
  • 87
  • 127