Copying an array in C - 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.

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 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).

Memory allocated for char (* arr)[X];

I'm a little bit lost on what this statement is doing. Is it making an array of X pointers? Or is it a pointer to an array of X chars? How much memory does it take on a 32-bit system?
If its the former, does it take 4*X bytes? If its the latter, is it just 1*X bytes?
This is a pointer which points to an array of X chars.
The C standard does not specify any particular size for a pointer. On common systems however, pointers are all the same size; so probably 4 bytes on your system.
X is part of the size of what is being pointed to, not the size of the pointer itself.

Why am I getting 8 always?

char *c = (char *)malloc(30*sizeof(char));
printf("%lu \n",sizeof(c));
In the above code I am trying to print the size of 'c'. No matter what number I give instead of '30' in the code, I get the sizeof(c) as 8.
What is the problem? How can I determine the size of an array?
Is length and size the same for an array?
At the moment you are asking for the size of a pointer which on a 64 bits machine is 8 bytes. Since this is a malloc and not a real array, you can't retrieve the size of the buffer allocated through c.
If c was declared as
char c[30];
You could determine size with
size_t size = sizeof(c)/sizeof(c[0])
But to be honest if I had to do that, I would just #define the array size even though the size calculation would be stripped out at compilation. It makes the code clearer in my opinion.
You are printing the size of a char * which in your system is 8.
If you want to know the amount of memory that was "malloc"ed you must store it somewhere. In your case your should store the 30 for future use if you are going to need it.
sizeof(c) means give me the size of the variable c. Since c is a pointer it's giving you back the number of bytes that the pointer takes up in memory. The fact you're seeing 8 suggests you're compiling for 64bit. On a 32bit built it would be 4.
It's your job to remember the size of the thing you've allocated. After all, you asked for an amount of memory, so you do know how much you allocated! In your case, size_t size = 30*sizeof(char) will give you the amount you've allocated.
sizeof is an operator, not a function, thus the compiler creates the code equivalent to something like sizeof(char *) and pointer of a char (depending on the architecture of course) is of 8 bytes.
Actually sizeof(*c) will return 1. The size of a mallocced buffer cannot be determined compile time (which is what sizeof does).
You're getting the size of the variable c, not the size of the memory region it points to. There's no way to get the size of an array inside a function because it always decays to pointer. You must store the size yourself. If you've passed the size to malloc then why can't you store that size to a variable?

Resources