Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you know how much space to allocate with malloc()?

I'm a total C newbie, I come from C#. I've been learning about memory management and the malloc() function. I've also came across this code:

char *a_persons_name = malloc(sizeof(char) + 2);

What I don't understand is how much space this is allocating for a_persons_name. Is it allocating 2 characters (eg. AB) or something else?

I also know that you can sometimes get "lucky" with malloc and use unallocated space (which can result in data corruption and seg faults). So how do I know how much space I'm allocating and how much I will need?

like image 200
Kredns Avatar asked Aug 08 '09 04:08

Kredns


People also ask

How much space does malloc take?

The malloc() function reserves a block of storage of size bytes. Unlike the calloc() function, malloc() does not initialize all elements to 0. The maximum size for a non-teraspace malloc() is 16711568 bytes.

How can you determine the size of an allocated portion of memory?

Q) How can you determine the size of an allocated portion of memory? In C language, we can calculate the size of the static array using the sizeof operator but there is no operator to calculate the size of the dynamically allocated memory.

How can I check malloc size?

The malloc line allocates a block of memory of the size specified -- in this case, sizeof(int) bytes (4 bytes). The sizeof command in C returns the size, in bytes, of any type.

How can you tell the size of memory allocated by malloc using pointer?

ptr = (cast-type*) malloc(byte-size) For Example: ptr = (int*) malloc(100 * sizeof(int)); Since the size of int is 4 bytes, this statement will allocate 400 bytes of memory. And, the pointer ptr holds the address of the first byte in the allocated memory.


4 Answers

That snippet is allocating enough space for a 2-character name.

Generally the string buffer is going to be filled from somewhere, i.e. I/O. If the size of the string isn't known ahead of time (e.g. reading from file or keyboard), one of three approaches are generally used:

  • Define a maximum size for any given string, allocate that size + 1 (for the null terminator), read at most that many characters, and error or blindly truncate if too many characters were supplied. Not terribly user friendly.

  • Reallocate in stages (preferably using geometric series, e.g. doubling, to avoid quadratic behaviour), and keep on reading until the end has been reached. Not terribly easy to code.

  • Allocate a fixed size and hope it won't be exceeded, and crash (or be owned) horribly when this assumption fails. Easy to code, easy to break. For example, see gets in the standard C library. (Never use this function.)

like image 190
Barry Kelly Avatar answered Oct 12 '22 10:10

Barry Kelly


Well, for a start, sizeof(char) is always 1, so you could just malloc(3).

What you're allocating there is enough space for three characters. But keep in mind you need one for a null terminator for C strings.

What you tend to find is things like:

#define NAME_SZ 30
: : :
char *name = malloc (NAME_SZ+1);

to get enough storage for a name and terminator character (keeping in mind that the string "xyzzy" is stored in memory as:

+---+---+---+---+---+----+
| x | y | z | z | y | \0 |
+---+---+---+---+---+----+

Sometimes with non-char based arrays, you'll see:

int *intArray = malloc (sizeof (int) * 22);

which will allocate enough space for 22 integers.

like image 28
paxdiablo Avatar answered Oct 12 '22 09:10

paxdiablo


malloc() will allocate a block of memory and return a pointer to that memory if successful, and NULL if unsuccessful. the size of the block of memory is specified by malloc's argument, in bytes.

the sizeof operator gives the size of its argument in bytes.

char *someString = malloc(sizeof(char) * 50)

this will allocate enough space for a 49 character string (a C-style string must be terminated by a NULL ('\0') character) not including the NULL character, and point someString at that memory.

It looks like that code in your question should be malloc(sizeof(char) * 2);, as sizeof(char) + 2 doesn't make sense.

note that sizeof(char) is guaranteed to always equal 1 (byte) -- but the memory representation of other types (such as long) may vary between compilers.

The way that you get (un)lucky with dynamically allocated memory is if you try to read/write outside of memory you have allocated.

For example,

char *someString = malloc(10);
strcpy(someString, "Hello there, world!");
printf("%s\n", someString);

The first line allocates enough room for 9 characters, and a NULL character.
The second line attempts to copy 20 characters (19 + NULL) into that memory space. This overruns the buffer and might cause something incredibly witty, such as overwriting adjacent memory, or causing a segfault.

The third line might work, for example if there was allocated memory right beside someString, and "Hello there, world!" ran into that memory space, it might print your string plus whatever was in the next memory space. If that second space was NULL terminated, it would then stop--unless it wasn't, in which case it would wander off and eventually segfault.

This example is a pretty simple operation, yet it's so easy to go wrong. C is tricky -- be careful.

like image 42
Carson Myers Avatar answered Oct 12 '22 08:10

Carson Myers


Your call to malloc will allocate 3 bytes of memory. sizeof(char) is 1 byte and 2 bytes are indicated explicitly. This gives you enough space for a string of size 2 (along with the termination character)

like image 1
Brandon E Taylor Avatar answered Oct 12 '22 08:10

Brandon E Taylor