Does malloc takes care of memory allignment? - c

I allocated 5 bytes of memory using malloc and I was able to use those 5 bytes to store characters or integers.
For example,use the first byte to store a character and the next four bytes to store an integer.
How does malloc takes care of memory allignment issues?

malloc
If allocation succeeds, returns a pointer to the lowest (first) byte
in the allocated memory block that is suitably aligned for any object
type.
So the memory block is aligned for any object type.
use the first byte to store a character and the next four bytes to
store an integer.
That's not valid. You need to either bundle the char and integer together in a structure (which might include padding) or have 2 separate memory blocks for them. Or serialize them (which is another issue).

Related

Confused on how memory is allocated

I am watching a video on pointers and memory and I'm confused because I thought memory addresses are 1 byte but in the video he is saying they are 32-bits (4 bytes) and that if we had int a = 2 it would be stored in one memory address, but wouldn't an integer be stored across 4 separate memory addresses since they are a maximum 4 bytes long?
A pointer points to a single byte. When you're storing something larger than a byte, it's spread across multiple consecutive bytes, and the pointer points to the first of these bytes. The compiled code uses instructions that can read and write multiple bytes from memory to process the whole thing.
So you're correct, a 32-bit integer will be stored in 4 separate (but consecutive) memory locations.
This is why we have to declare the types of pointers in C. When you derefence the pointer, the type is used to determine how many bytes to read or write starting at that address.

Does storing a pointer take more memory than the byte that it's pointing to?

My questions are how where are the pointer values stored and do they take up more space in memory than the things they point to. For example, if I have a 64 bit pointer which i use to point to a byte of information in memory; where is the value of the pointer stored and does it take up more space than the data itself?
An example of my question written in C
char data = 10;
char* charPointer = &data;
doesn't charPointer take up more space than the data since the pointer is 64 bit and the data is 8 bit?
PS: I'm currently trying to learn the basics of C.
where is the value of the pointer stored
The pointer's value is stored where you declared it to be stored; e.g. if you declared the pointer as a local variable, then it will be stored on the stack; OTOH if you allocated the pointer on the heap (or, more commonly, you included the pointer as a member-variable of an object that you allocated on the heap) then the pointer will be in the heap.
and does it take up more space than the data itself?
In this case, it does.
You can actually check for yourself how much space a value takes up:
printf("data takes up %zu bytes\n", sizeof(data));
printf("charPointer takes up %zu bytes\n", sizeof(charPointer));
If you are on a 64-bit machine, you should find that a pointer takes up 8 bytes, as you would expect.
The char that the pointer points to takes up one byte, but in many cases there will also be some padding bytes inserted to keep the alignment of the next item on the stack optimal for the CPU to access efficiently.
A pointer to a char takes more space than a char in practically every C implementation. (The C standard permits them to be the same size, but such implementations are at best rare and are more likely archaic or nonexistent.)
Nonetheless:
One may need a pointer to point to one of a selection of objects or to manage objects or to connect them in various ways.
A pointer may point to objects much larger than a char.
A pointer may point to the first of many elements in an array, so one pointer can provide access to many objects.

Does sizeof returns the amount of memory allocated?

I read that:
sizeof operator returns the size of the data type, not the amount of memory allocated to the variable.
Isn't the amount of memory allocated depends on the size of the data type? I mean that sizeof will return 4 (architecture-dependent) when I pass int to it.
Am I missing something here?
sizeof returns the number of bytes that a variable or stack allocated array occupies.
Examples:
sizeof(char)=1 (in most configurations)
But sizeof(char*)=8 (depending on the platform)
If you dynamically allocate memory with malloc, you will receive a pointer to that block of memory. If use the sizeof on it, you will just get the size of the pointer.
However, sizeof() a stack allocated array like when you write int a[10] is the size of the allocated memory (so 4*10)
The size of the pointer doesn't depend on the size of the datatype it represents. (On 32 bit platforms, a pointer is 32bit)
The text you quote is technically incorrect. sizeof variable_name does return the size of memory that the variable called variable_name occupies.
The text makes a common mistake of conflating a pointer with the memory it points to. Those are two separate things. If a pointer points to an allocated block, then that block is not allocated to the pointer. (Nor are the contents of the block stored in the pointer -- another common mistake).
The allocation exists in its own right, the pointer variable exists elsewhere, and the pointer variable points to the allocation. The pointer variable could be changed to point elsewhere without disturbing the allocation.
sizeof returns the number of bytes
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type.
but the size of each byte is not guaranteed to be 8. So you don't obtain directly the amount of memory allocated.
A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined
anyway you can deduce the amount of memory allocated using the CHAR_BIT constant, which contains the number of bit is a byte.
"Memory allocation" in C typically refers to explicit allocation (i.e: on the heap - malloc() and friends), or implicit allocation (i.e: on the stack).
As you've defined, sizeof() returns the size of the data type:
sizeof(char) - a single char
sizeof(void *) - an void pointer
If you call malloc(sizeof(int)), you're requesting "enough memory to hold the data for an int", which may be 4 bytes on your system... you may find that more memory than you requested is allocated (though this will typically be hidden from you, see canaries).
Additionally, if you call int *x = malloc(1024), and sizeof(*x), you might get 4, because an int happens to be 4 bytes... even though the memory you've allocated is 1 KiB. If you were to incorrectly call sizeof(x), then you'll get the size of a pointer returned, not the size of the type it points to. Neither of these (sizeof(*x) or sizeof(x)) will return 1024.

Getting a pointer to a memory address from a different pointer C

I'm writing my own memory allocater. I'm getting a pointer to mapped memory from mmap. From there, I want to be able to get a pointer to a different part of that mapped memory (like x bytes away from the current pointer). How can I do this? Memory management is very confusing to me.
mmap gives you a void* and C doesn't allow pointer arithmetic with those, but you can cast it to char* and then just add the number of bytes you want, e.g. mypointer + 16.
If you cast the pointer to a larger type (like int*), pointer arithmetic adds multiples of the size of that type. For example, if you add 16 to an int*, you're adding enough bytes for 16 int values (so 64 bytes, assuming sizeof(int) is 4).

Copying an array in C

What is wrong with this statement? It doesn't copy right.
memcpy(new_board1, board, sizeof(board));
memcpy accepts two memory addresses in form of pointers (destination and source) and the number of bytes to be copied. Now, sizeof doesn't return the size of the memory block a pointer points to, but the size of the pointer itself - either 4 bytes on a 32bit OS, or 8 bytes on a 64bit OS.
sizeof(board) gives you the size of the pointer itself, not the size of whatever it points at. You should replace it by the actual number of bytes you want to copy from board to new_board1. Without knowing how boardand new_board1 are declared, I cannot help you find that number.

Resources