Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

memcpy with destination pointer to const data

Tags:

c

pointers

memory

I always thought that an statement like const int *a means a is an int pointer to const data and as such one should not be able to modify the value it points to. Indeed if you do const int a [] = {1,2,3} and then issue a[0] = 10 you'll get compiler errors.

To my surprise, however, the following compiles without any warning and runs just fine.

#include <stdio.h>
#include <string.h> 

int main (){

    const int a [] = {1, 1, 1};
    const int b [] = {2, 2, 2};

    memcpy((void*) &a[0], (const void*)&b[0], 3*sizeof(int));

    int i;
    for (i=0; i<3; i++) printf("%d\n",a[i]);

    return 0;
} 

Why is this allowed? Is this due to the cast? When I do memcpy(&a[0], (const void*)&b[0], 3*sizeof(int)); compiler promptly generates the following warning:

cpy.c: In function ‘main’:
cpy.c:9:3: warning: passing argument 1 of ‘memcpy’ discards ‘const’ qualifier from pointer target type [enabled by default]
/usr/include/string.h:44:14: note: expected ‘void * __restrict__’ but argument is of type ‘const int *’
like image 459
mmirzadeh Avatar asked Sep 06 '12 22:09

mmirzadeh


People also ask

Does memcpy work with pointers?

Let's look at the parameters that the memcpy() function takes as input: Destination: Pointer to the destination array where data will be copied. Source: Pointer to the source of the data to copy. N: The number of characters to copy.

What can I use instead of memcpy?

memmove() is similar to memcpy() as it also copies data from a source to destination.

How memcpy works in C?

memcpy() function in C/C++ The function memcpy() is used to copy a memory block from one location to another. One is source and another is destination pointed by the pointer. This is declared in “string. h” header file in C language.

What is memcpy()?

memcpy() is used to copy a block of memory from a location to another. It is declared in string.h. // Copies "numBytes" bytes from address "from" to address "to" void * memcpy(void *to, const void *from, size_t numBytes);


1 Answers

You told the compiler to disregard the initial declaration when you performed the cast. It listened. That doesn't mean that your program is correct however. Modifying what was originally declared to be const results in undefined behavior (for example, the compiler is free to store that data in read only memory).

C doesn't hold your hand. If you chose to do something dangerous then it will let you.

like image 110
Ed S. Avatar answered Sep 23 '22 15:09

Ed S.