1

I have a book that says the following:

The malloc() allocation still has one slight problem. We still have to explain the left portion of the temperature malloc(). What is the (int *) for?

The (int *) is a typecast. You’ve seen other kinds of typecasts in this book. To convert a float >value to an int, you place (int) before the floating-point value, like this:

aVal = (int)salary;

The * inside a typecast means that the typecast is a pointer typecast. malloc() always returns a character pointer. If you want to use malloc() to allocate integers, floating points, or any kind of data other than char, you have to typecast the malloc() so that the pointer variable that receives the allocation (such as temps) receives the correct pointer data type. temps is an integer pointer; you should not assign temps to malloc()’s allocated memory unless you typecast malloc() into an integer pointer. Therefore, the left side of the previous malloc() simply tells malloc() that an integer pointer, not the default character pointer, will point to the first of the allocated values.

temps:

int * temps; /* Will point to the first heap value */
temps = (int *) malloc(10 * sizeof(int)); /* Yikes! */

After reading similar threads, it's said that malloc() returns a pointer of type void, not of type character. Am I missing something? I'm aware that it's not needed to typecast malloc() in C.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
Nameless
  • 383
  • 2
  • 11
  • 3
    `malloc()`, on success, returns the beginning address to a block of memory of the size requested. On failure, `NULL` is returned. In C, there is no need to cast the return of `malloc`, it is unnecessary. See: [Do I cast the result of malloc?](http://stackoverflow.com/q/605845/995714) Consider `int *temps; if (!(temps = malloc (10 * sizeof *temps))) { perror("malloc-temps"); exit (EXIT_FAILURE); }` Always **validate** EVERY allocation by checking the return. – David C. Rankin Apr 24 '22 at 03:32
  • 2
    The return is just an *Address*. So `void*` allows assignment to any type.. – David C. Rankin Apr 24 '22 at 03:38
  • 8
    Your book is obsolete by about 30 years. – user207421 Apr 24 '22 at 03:38
  • @DavidC.Rankin "The return is just an Address." Isn't it a pointer that is returned? Addresses can't be typecasted as fas as I'm concerned. – Nameless Apr 24 '22 at 03:48
  • Pointers are addresses. They can be typecast to other pointer types (with some exceptions). They can also be typecast to `uintptr_t`. – Daniel Walker Apr 24 '22 at 03:50
  • @DanielWalker It is my understanding that pointers are variables that *hold* addresses. – Nameless Apr 24 '22 at 03:53
  • That's correct. However, it's fine to refer to a pointer as an address in the same way you refer to an `int` as an integer instead of a variable that *holds* an integer. – Daniel Walker Apr 24 '22 at 03:55
  • Out of curiosity, what's the book? – Daniel Walker Apr 24 '22 at 03:56
  • @DanielWalker C Programming Absolute Beginner's Guide :p – Nameless Apr 24 '22 at 03:58
  • @Nameless A few links that provide basic discussions of pointers may help. [Difference between char *pp and (char*) p?](https://stackoverflow.com/a/60519053/3422102) and [Pointer to pointer of structs indexing out of bounds(?)...](https://stackoverflow.com/a/60639540/3422102) (ignore the titles, the answers discuss pointer basics) (An aside... I used to travel `Nameless` road between `I-35` and `FM 1431` going to Jonestown on Lake Travis from Dallas -- wonderful drive in the early 1980's) – David C. Rankin Apr 24 '22 at 04:07
  • You should return that book, demand your money back, it is inane garbage. If you want to learn C, get K&R. It is dense, but readable. I would rather 120 pages of slow and careful reading than 700 pages of filler. – mevets Apr 24 '22 at 05:54
  • The function `void *malloc(size_t size);` returns a `void*` pointer. It is correct to say that is an address. It is a number (the address of the start of a region of memory) which can be assigned to any type of pointer variable. – Weather Vane Apr 24 '22 at 07:36
  • The third edition of that book fro 2014 and "updated for C11" contains that text - it is incorrect - it returns a `void*`. Moreover it is poor advice - you should specifically _not_ cast the return of `malloc()` in C. (https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Clifford Apr 24 '22 at 08:51

3 Answers3

5

Prior to the 1989 standard, C did not have a "generic" pointer type; pointer types were not compatible, so to assign a char * value to an int * variable (or vice versa) you needed to explicitly cast the value to the target type.

Also prior to the 1989 standard all the memory allocation functions (malloc/calloc/realloc) returned char *, so if you were assigning the result to a different pointer type, you had to use a cast:

int *ptr = (int *) malloc( some_size );

This, frankly, was a pain in the ass. It was recognized that C could use some kind of a "generic" pointer type, so the void * type was introduced, along with the rule that void * values could be converted to other pointer types (and vice versa) without needing a cast. The memory allocation functions were changed to return void *, so a cast is no longer necessary:

int *ptr = malloc( some_size );

You cannot dereference a void * - the result would be a void type, which has no values and no size. For the same reason, you can’t do pointer arithmetic or use the subscript operator on a void *.

John Bode
  • 119,563
  • 19
  • 122
  • 198
2

As user207421 mentioned in the comments, your book is most likely pretty old. Originally, C didn't have a generic pointer type (i.e., void*). I forget when this was added. The closest thing back then was char* since every pointer, no matter its type, can be safely cast to and from a char* (sort of).

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
  • 1
    3rd edition, 2014 "updated for C11" contains that text. So not old enough to contain such an error. `void*` at least since ANSI standardisation in 1989 (and K&R second edition), but compiler support predated that. – Clifford Apr 24 '22 at 08:54
1

Does malloc() always return a character pointer?

No. Since C89, malloc() returns a void *.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256