Reputation:
I call a function that swaps shifts a massage in memory:
for (int i = now->size - 1; i >= 0; i--)
{
void *address2 = prev->start_address + i;
void *address1 = now->start_adress + i;
address1 = address2;
address2 = '\0';
}
So basically I have two addresses one pointing to the first start location the other to the second start location that the content have to be pasted.
The problem is that the only solution that I find is to add int
( this is i value ) and prev->start_adress
( that is void*) as I have shown. I want to do it correctly, i cant change the void pointer to int. Is there any other possibilities.
My errors:
error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arit]
214 | void *address2 = prev->start + i;
Warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arit]
215 | void *address1 = now->start + i;
Supporting information: I have a linked list(full of segementdescriptors) and a "memory" that is a simple array[].Similar how malloc works.
typedef struct segmentdescriptor
{
Byte allocated;
void *start;
size_t size;
struct segmentdescriptor *next;
} Node;
the start pointers point to the begining of the allocated space in the array[].
Update: The simplest way is to use typecast to do arithmethics on void pointers if you know their size like :
char *address2 = (char *)prev->start + i;
If you dont know the type, it is impossible because for example:
char *pointer
points to one byte of memory and if you write pointer++
goes
to next byte. int *pointer
is lets say points four byes. if you write pointer ++
goes to the four bytes after the four bytes.
There are also good answers below. Thanks for all answers.
Upvotes: 0
Views: 331
Reputation: 44264
Regarding these warnings:
warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arit]
214 | void *address2 = prev->start + i;
Warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arit]
215 | void *address1 = now->start + i;
On any modern computer the value of a pointer is a memory address (typically a virtual memory address). When you add one to a pointer, it's value (aka the memory address) is incremented by the sizeof the pointed to type.
Example:
TYPE* p = SOME_ADDRESS; // The value of p is now SOME_ADDRESS
p = p + 1; // The value of p is now SOME_ADDRESS + sizeof(TYPE);
p = SOME_ADDRESS; // The value of p is now SOME_ADDRESS
p = p + i; // The value of p is now SOME_ADDRESS + i * sizeof(TYPE);
In other words: In order to add an integer value to a pointer, we need to know the size of the element that the pointer points to.
And that is your problem. You have void-pointers so you would need to know the "sizeof void" in order to update the pointer. But the sizeof void can be anything and isn't defined by the standard. Apparently, your compiler has a non-standard extension that allows sizeof(void)
. Consequently, your compiler only gives you a warning.
Regarding this error:
error: invalid conversion from ‘void*’ to ‘char*’
It comes from some code post you didn't post. Further it shows that you use a c++ compiler instead of a c compiler.
Finally: Even if the pointer arithmetic was valid, your code do nothing.
for (int i = now->size - 1; i >= 0; i--)
{
void *address2 = prev->start_address + i;
void *address1 = now->start_adress + i;
address1 = address2; // This only change the value of the pointer
// It doesn't change the memory that the
// pointer points to
address2 = '\0';
}
It's not fully clear what you are trying to do but perhaps this is what you are looking for:
for (int i = now->size - 1; i >= 0; i--)
{
char *address2 = (char*)prev->start_address + i;
char *address1 = (char*)now->start_adress + i;
*address1 = *address2;
*address2 = '\0';
}
Upvotes: 0
Reputation: 310920
The type void
is always an incomplete type. That is the size of an object of the type void
is unknown. So you may not use the pointer arithmetic with a pointer of the type void *
though some compilers have their own language extensions that allow the pointer arithmetic with the type void *
the same way as with pointers of the type char *
.
So these statements
void *address2 = prev->start + i;
void *address1 = now->start + i;
are incorrect according to the C Standard because the pointer start
has the type void *
.
Also it seems these statements
address1 = address2;
address2 = '\0';
are doing not what you thing.
For starters this statement
address1 = address2;
assigns one pointer to another pointer though it looks like actually you want to assign a value pointed to by one pointer to the memory pointed to by another pointer.
And this statement is equivalent to
address2 = NULL;
That is it does not set the pointed memory with the terminating zero character '\0'
.
If as you are saying these pointers deal with a message (a string) then you need to cast the pointers to the type char *
.
As for this your phrase
I call a function that swaps shifts a massage in memory:
then it is totally unclear what you are trying to do using the for loop because the loop in any case does not make a sense.
If you need to copy one character array into another character array then use the standard C function memcpy
or memmove
depending on what and how you are trying to copy arrays.
Upvotes: 0
Reputation: 67476
I do not really understand what shifts a massage in memory
is, but if you just want to copy one memory location to another you can
Use memcpy
or memmove
(if memory locations overlap)
memcpy(now->start_adress, prev->start_address, now->size);
Write your own function to copy the memory
void *mymemcpy(void *dest, const void *src, size_t size)
{
unsigned char *cdest = (unsigned char *)dest; //cast for C++ compiler
const unsigned char *csrc = (unsigned char *)src;
while(size--) *cdest++ = *csrc;
return dest;
}
void *mymemcpy(void *dest, const void *src, size_t size)
{
unsigned char *cdest = (unsigned char *)dest; //cast for C++ compiler
const unsigned char *csrc = (unsigned char *)src;
for(size_t index = 0; index < size; index++) cdest[index] = csrc[index];
return dest;
}
void *mymemcpy(void *dest, const void *src, size_t size)
{
unsigned char *cdest = (unsigned char *)dest; //cast for C++ compiler
const unsigned char *csrc = (unsigned char *)src;
for(size_t index = 0; index < size; index++) *(cdest + index) = *(csrc + index);
return dest;
}
C standard does not allow any pointer arithmetic on void
pointers. gcc
has an extension which treats the void *
as pointer to char allowing the arithmetics, but not allowing dereferencing.+
Upvotes: 1