Trying to keep this simple (bad terminology used here) -- regarding malloc():
1. The way this is commonly done is to force-cast the result of malloc() into whatever the type of thing is that you plan on using. E.g.
char *foo = (char *)malloc(1024);. malloc() on UNIX machines tends to be
void *malloc, which is why the force-cast is needed. Same goes for calloc() and others.
This is necessary on some compilers and not on others. For example, with FreeBSD's gcc 4.2.1, I do not need to force-cast in most situations (yes really:
unsigned short *foo = malloc(123); emits no warnings with -Wall or other flags).
2.
malloc(5) will ask for 5 bytes. However, deep inside of libc, things are broken up into pages of a large size (on most platforms it's 4096, but I've heard of some using 8192) because memory should be aligned appropriately to page sizes, otherwise excessive fragmentation can occur. So internally to libc what's actually going on is a 4KByte allocation, but from your program's perspective you don't know that (nor do you need to know that).
My general guideline (and this is just my preference): I don't bother using malloc() on anything smaller than 512 bytes. I just use preallocated buffers (e.g.
char foo[512]). If I have **many** of these, I may end up using malloc and splitting things up into portions myself, or (more commonly) make an array of pointers and use malloc() for all of those (recursively freeing all of them when done).
3. As for your char vs. short issue -- if you have
unsigned short *buf = (unsigned short *) malloc(numberofbytes); then that should not be throwing a warning.
Just remember: malloc wants bytes, but the
unsigned short * declaration means allocating a pointer
to a bunch of unsigned shorts. It's therefore up to you to ensure that you deal with the byte vs. word (2 bytes) situation in your loops and code. This is where
sizeof(unsigned short) and some simple math (multiplication or division, depending on what you need) can make your life easier.
You need to be very careful about not mixing up chars/bytes vs. shorts/words in loops and so on. It's very easy for someone to forget what they're working with and overrun a buffer (which may or may not cause a segfault, depending on however ld.so and friends chose to allocate the heap, ditto with malloc).
Real-world example, with gdb proving that:
Code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <inttypes.h>
5
6 #define mybufsize_bytes 4096 * sizeof(unsigned short)
7 #define mybufsize_short mybufsize_bytes / sizeof(unsigned short)
8
9 int main(int argc, char *argv[])
10 {
11 size_t i;
12 unsigned short *buf = malloc(mybufsize_bytes);
13
14 memset(buf, 0, mybufsize_bytes);
15
16 buf[4094] = 0xfeed; /* Note offset -- this would be byte offsets 8188-8189 of buf */
17 buf[4095] = 0xface; /* Note offset -- this would be byte offsets 8190-8191 of buf */
18
19 for (i = 0; i < mybufsize_short; i++) {
20 printf("buf[%4zu] (short) = 0x%04" PRIx16 "\n", i, buf[i]);
21 }
22
23 free(buf);
24
25 return 0;
26 }
Code:
$ gdb x
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
(gdb) l
3 #include <string.h>
4 #include <inttypes.h>
5
6 #define mybufsize_bytes 4096 * sizeof(unsigned short)
7 #define mybufsize_short mybufsize_bytes / sizeof(unsigned short)
8
9 int main(int argc, char *argv[])
10 {
11 size_t i;
12 unsigned short *buf = malloc(mybufsize_bytes);
(gdb) l
13
14 memset(buf, 0, mybufsize_bytes);
15
16 buf[4094] = 0xfeed; /* Note offset -- this would be byte offsets 8188-8189 of buf */
17 buf[4095] = 0xface; /* Note offset -- this would be byte offsets 8190-8191 of buf */
18
19 for (i = 0; i < mybufsize_short; i++) {
20 printf("buf[%4zu] (short) = 0x%04" PRIx16 "\n", i, buf[i]);
21 }
22
(gdb) b 18
Breakpoint 1 at 0x40072e: file x.c, line 18.
(gdb) r
Starting program: /home/jdc/x
Breakpoint 1, main (argc=1, argv=0x7fffffffeaa8) at x.c:19
19 for (i = 0; i < mybufsize_short; i++) {
(gdb) p/x (unsigned char[8192]) *buf
$1 = {0x0 <repeats 8188 times>, 0xed, 0xfe, 0xce, 0xfa}
(gdb) p/x (unsigned short[4096]) *buf
$2 = {0x0 <repeats 4094 times>, 0xfeed, 0xface}
(gdb) c
Continuing.
buf[ 0] (short) = 0x0000
buf[ 1] (short) = 0x0000
buf[ 2] (short) = 0x0000
buf[ 3] (short) = 0x0000
...
buf[4093] (short) = 0x0000
buf[4094] (short) = 0xfeed
buf[4095] (short) = 0xface
Program exited normally.