How does memcpy works with void pointers? - c

I am trying to memcpy from one ptr to another. I know the size that I want to copy. Both the destination and source pointers are void pointers. Is this valid? Does it actually copy the ELEMENT_SIZE (integer like 128) from source to the destination? I know this is not the most ideal thing to do. But I want to know if this works.
memcpy(to_add, element_ptr, ELEMENT_SIZE);

Does it actually copy the ELEMENT_SIZE (integer like 128) from source
to the destination?
Yes, If you know the size information,then its working fine.
See the reference link : http://www.cplusplus.com/reference/cstring/memcpy/

Parameter descriptions for memcpy from the documentation:
void * memcpy ( void * destination, const void * source, size_t num );
destination: Pointer to the destination array where the content is to be copied,
type-casted to a pointer of type void*.
source: Pointer to the source of data to be copied, type-casted to a pointer of type const void*.
num: Number of bytes to copy. size_t is an unsigned integral type.
memcpy simply takes num bytes starting from the address source and copies them to memory starting at address destination.
A pointer is a fixed length memory address, regardless of type. It does not matter whether the pointer is char * (points to character data), int * (points to integer data), or void * (points to data of unknown type), it still just points to memory.
Because memcpy copies an explicit number of bytes, the type of data being pointed to is irrelevant; it just need memory addresses to data.

It does not matter what pointer it is really. It is a very plain process of having two memory addresses and engaging a copy.

Related

Why in kernel code some addresses of variables are stored in char pointers?

I was going through the kernel source code and I found this statement:
char *tagp = NULL;
/* ...CODE... */
tagp = &descriptor->b_data[sizeof(journal_header_t)];
I wonder why this address is stored in a char pointer rather than any other type more related to what it represents, such as maybe void if this is an opaque.
The individual cases may have their explicit use-cases, but in general, this is useful for two reasons.
a char pointer has the same alignment requirement as a void pointer.
char pointer can be used to access (via dereference) any other type of data, starting from lowest addressed byte of the object (Successive increments of the
result, up to the size of the object, yield pointers to the remaining bytes of the object.). Also, pointer arithmatic (if needed, is allowed on char pointer, not on void pointers).
Thus, using a char * is more robust.
If it is an old code then the type char * was used instead of the type void * because the type void was absent in the C at that time.
Because in the kernel we need to do some operatings on byte.And then we can do operatings like &,<<,>>.

Is it a valid operation to cast a void* pointer to char* pointer and doing pointer arithmetics on it?

I have a Pointer(void*) to a malloc'ed block/array in memory, and I know the Size of the data structure that is stored in that block. I want to be able to iterate over the block to get access to any single value.
Program knows:
that void* Pointer will point to the start of this malloc'ed block of memory.
the Size[in bytes] of each value, but not the data structure that is actually stored.
the Capacity[in bytes]: potential amount of those values(how much memory is allocated)
This means that I have malloc'ed: Capacity*Size_of_value bytes, and I want to get a pointer to any value that is inside that block, by:
Casting the void* Pointer into char* Pointer.
Adding a required multiple of Size_of_value to the char*Pointer: thus getting a pointer to any required value.
What I learned, is that adding N to a char* pointer, causes it to move forward by N bytes. And as I know that the pointer has to be moved forward by [amount] of bytes, I can add [amount] to this char* pointer.
I couldn't find a proper source for this, and generally only found out for sure that arithmetics on a void* isn't allowed.
From what I hacked together so far, it seems to work properly, as long as the stored structure has a constant, known size. A flexible array member in the struct breaks my current implementation. This is a shortcoming that I'm planning to fix by creating an extension: the list will hold a pointer to an array of pointers, and those pointers will give access to the actual values.
Context that might or might not be useful:
I am working on an implementation of a list data structure, and I implemented it as basically a dynamic array(expanding and shrinking whenever needed) with more interface.
I know about linked lists, and I'm also planning to implement them as a different exercise.
I defined the list like this:
typedef struct TLIST_
{
size_t size_of_value; // size [in bytes] of each record stored in the list
size_t list_capacity; // memory has been allocated for this many values(size can't be larger than this)
size_t list_size; // number of stored records
void* pointer_to_zero; // address of the content
} tlist;
// The list has a few other values for various options and operations(e.g.: disallowing it to expand automatically, displaying the content), but those four values is all that's needed for this problem.
The function for getting a pointer to a value at given index:
void* tehlist_generic_getPointerToIndex(const tlist* list__, const int index__)
{
const int capacity = (*list__).list_capacity;
if( index__ >= 0 && index__ < capacity )
{
// Move pointer forward by a given amount of bytes, through casting the void* to a char*
// 1. Can't do pointer arithmetic on void*, but can on char*
// 2. char* is defined as 1[unit or byte],
// thus moving char* forward by N, causes it to move as if we were moving through a pointer that was of size N
void* pointer_to_index = (*list__).pointer_to_zero;
const size_t bytes_forward = (*list__).size_of_value*index__;
pointer_to_index = (char*)(pointer_to_index) + ( bytes_forward );
return pointer_to_index;
}
return 0;
}
Additional information I found:
GNU C compiler offers a C language extensions that allows arithmetic on void*, by treating it as if it had size of 1 (like it was casted into char*):
https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
This isn't allowed in ISO C, only in GNU C.
Yes, casting to char * is always legal, dereferencing that pointer is only legal within the bounds of the allocated block.
The C99 standard says in 6.3.2.3:
A pointer to void may be converted to or from a pointer to any
incomplete or object type. A pointer to any incomplete or object type
may be converted to a pointer to void and back again; the result shall
compare equal to the original pointer.
So yes it is perfectly valid as long as you do the arithmetic with the pointer of the actual type(in this case char*).

adding an integer to a char array in c

It may be silly question but still am not getting it.
I do have a char array say
char arr[100] having some data
char arry[100] ---- some data;
int test;
memcpy(&test,array+4,sizeof(int))
What does this memcpy will do
Thanks
SKP
This might be useful in so-called serialization of data.
Say, if someone saved an integer into a file.
Then you read the file into a buffer (arry in your case) as a stream of bytes. Now you want to convert these bytes into real data, e.g. in your case integer test which has been stored with offset 4.
There are several ways to do that. One is to use memcpy to copy bytes into area where compiler would treat them as an integer.
So to answer your question:
memcpy(&test,array+4,sizeof(int))
...will copy sizeof(int) number of bytes, starting from 4-rth byte from array into memory allocated for variable test (which has type int). Now test has the integer value which was saved into arry originally, probably using the following code:
memcpy(array+4, &original_int, sizeof(int))
Doing this requires some knowledge of hardware and the language. As there are many complications, among which:
byte order in integers.;
data alignment;
It just copy the element array[4] to variable test. On 32-bit machine sizeof(int) = 4. memcpy will copy 4 bytes to the address &test which can hold 4 bytes.
This will copy probably 4 bytes (depending on your machine and compiler--your int might be bigger or smaller) from the 4th through 7th bytes of arry into the integer test.
According to the documentation of memcpy() :
void * memcpy ( void * destination, const void * source, size_t num );
Copies the values of num bytes from the location pointed by source directly to the memory block pointed by destination.
In your case :
num=sizeof(int)
destination=&test A pointer to test
source=&array[4] A pointer to the fourth element of the array of char array
Hence, if sizeof(int)==4 it will copy array[4], array[5],array[6] and array[7] to test
There are questions that can help you understand the memory layout of integers :
int32 storage in memory
How is an integer stored in memory?
There is also an issue with endianless : on my computer, array[4] corresponds to the least significant byte.
Consequently, if array[7]=0x80 and array4]=array[5]=array[6]=0x00 then test will contain 00000080 and test will worth -2^31.
if array[7]=0x2A and array[5]=array[6]=array[4]=0x00 then test will contain 2A000000 and test will worth 42 (that is 0x0000002A).
Here is a test code to be compiled by gcc main.c -o main
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[]){
char array[100];
int test;
printf("sizeof(int) is %ld\n",sizeof(int));
array[4]=0x00;
array[5]=0;
array[6]=0;
array[7]=0x80;
memcpy(&test,&array[4],sizeof(int));
printf("test worth %d or(hexa) %x\n",test,test);
array[4]=0x2A;
array[5]=0;
array[6]=0;
array[7]=0x00;
memcpy(&test,&array[4],sizeof(int));
printf("test worth %d or(hexa) %x\n",test,test);
return 0;
}
Generally the C library function void *memcpy(void *str1,const void *str2,size_t n) copies n characters from memory area str2 to memory area str1, where:
str1 – this is pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*
str2 -- this is pointer to source of data to be copied, type-casted to a pointer of type void*
n -- this is the number of bytes to be copied
memcpy returns a pointer to destination, which is str1
In your case, is copied the contents of the array, from the address pointed to by array[4] up to sizeof (int) bytes (4 bytes in this case, if you have a 32bit machine), the address pointed to by test

Confused with results of sizeof() function

I'm trying to write a function that converts a base 10 integer to a binary number.
I am constructing the function like this:
void dec2bin(int dec, char * bin);
The function will store the binary result by means of the pointer in the argument. It is passed a variable declared elsewhere as follows:
char *r1 = (char *)malloc(24);
The first thing the function has to do is fill the "24 bit result" with all zeros. It works great now since I've coded it based on me knowing the "size," but I can't figure out how to determine the "size" of an arbitrary "r1". Every way I can think to use the sizeof function does not give me 24.
I am confused at this point, and not connecting the relationship between the respective sizes of a char, char*, etc and how I can use those sizes to get what I'm looking for with respect to "r1".
Would someone mind giving me a pointer? Pun intended.
Thanks!
You may just pass the size as another parameter:
void dec2bin(int dec, char * bin, size_t max_chars);
I can't figure out how to determine the "size" of an arbitrary "r1".
You cannot do that: the information about the size that you passed to malloc is irreversibly lost after the call. All you have at that point is a pointer to the chunk of at least 24 bytes of memory. If you need the size, you need to store it somewhere else - for example, in a separate variable that you carry around.
Two typical work-arounds to this issue include (1) storing a zero-terminated string in the allocated space, and using the length of that string as the proxy to the size of the allocated chunk, and (2) defining your own structure that contains both the size and the allocated pointer. Neither solution is ideal, but at least the choice is with you.
The type of r1 is a char* (char pointer), so, like all pointers, its size is 4 (or 8, depending on your situation). No matter the size of the memory block you're allocating to it.
You can't retrieve the size of the allocated block from a pointer, so if you need the size later, you will have to remember the size yoursef (e.g. by storing it in a different variable).
r1 is a variable of pointer type, and its size is fixed and always the same (just like the size of any variable of a given type), which is no larger than (and usually equal to) sizeof(void *). What you really want to know is the size of the array that's sitting at *r1 (note the asterisk), and that is something you cannot know. You have to keep track of it yourself, typically like this:
size_t const n = get_some_number();
foo * p = calloc(n, sizeof(foo));
Now you use the pair (p, n) to describe your dynamic array.
(Note that C99 and C11 have the notion of a variable-length array, in whose context sizeof does actually (sometimes) give you the actual array size, but that's a somewhat murky affair, and in any case it isn't what you asked for.)
When you allocate memory, you get back a pointer, which has a fixed size, so there's no way to get the size of the allocated memory with sizeof.
As others have said, if it's just a pointer, you won't be able to tell anything (unless it's zero-terminated, in which case you can just iterate until you hit an element equal to zero (not the character '0')).
However, if you set it up as follows, you can actually see the buffer size after calling sizeof()... at least until you send it to a function, where the array decays to a plain char* pointer.
void test( char* s )
{
int i2 = sizeof( s ) / sizeof( char );
}
char c1[] = "Testing!";
int i1 = sizeof( c1 ) / sizeof( char ); // i1 is 9 (size of buffer)
test( c1 ); // i2 is 4 (size of pointer)

c: size of void*

I'm a bit confused with a void* pointer in C. Especially after reading this question: Is the sizeof(some pointer) always equal to four?, where one person says there is no guarantee that sizeof(int *) == sizeof(double *)
My question is: is there a guarantee of sizeof(void*) >= sizeof(any other pointer type)?
In other words, can I always assign a some_type* pointer to a void* pointer and then get it back as some_type*?
Only data pointers. void * can hold any data pointer, but not function pointers.
Here is a C FAQ.
void *'s are only guaranteed to hold object (i.e. data) pointers; it
is not portable to convert a function pointer to type void *. (On some
machines, function addresses can be very large, bigger than any data
pointers.)
As for the first part, yes, different types can have pointers of different sizes:
The value stored in the pointer is an address to memory. If you're on a 32-bit system, that pointer into memory is going to be 32 bits (or four bytes) long. If you're on a 64-bit system, that pointer into memory is going to be 64 bits (or eight bytes) long.
The size of the data that holds the location in memory has nothing to do with the size of the data represented at that location in memory.
As for how a char * differs from a double *, the char * can point to any location, but the double * has to point to something along an eight-byte boundary. Larger data has to be aligned according to the rules of the processor you're on. So, pointers to small data are not generally compatible with pointers to large data (e.g. you shouldn't point a double * pointer to a char * address); but you're save going in the other direction (e.g. you can point a char * pointer to a double * address).

Resources