473,386 Members | 1,726 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

cast in memcpy()

Hi,

I am a bit confused over the correct usage of memcpy(). Kindly help me
clear the confusion.

The linux manpage for memcpy(3) gives me the following prototype of
memcpy(3):
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

Now, I have a char array (char arr[256]), and a pointer to a structure
(PSMessage *p). I have to memcpy() the contents of this structure to
the char array. I am doing it like this:

memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);

Do I need the cast here ? Or the way I am trying to do it is correct ?
I have not tested the code, so I am not sure of it either.

Thanks in advance.

Cheers,
Amarendra

--
Life's battles don't always go to the stronger or the faster man,
But sooner or later the man who wins is the man who thinks he can.
Nov 14 '05 #1
16 15712
ro**@zworg.com (Amarendra GODBOLE) writes:
memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);


Your informant is wrong. No such casts are necessary in C.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #2
Amarendra GODBOLE wrote:
Hi,

I am a bit confused over the correct usage of memcpy(). Kindly help me
clear the confusion.

The linux manpage for memcpy(3) gives me the following prototype of
memcpy(3):
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

Now, I have a char array (char arr[256]), and a pointer to a structure
(PSMessage *p). I have to memcpy() the contents of this structure to
the char array. I am doing it like this:

memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);

Do I need the cast here ? Or the way I am trying to do it is correct ?
I have not tested the code, so I am not sure of it either.


That "someone" is blowing smoke or else using a language other than C.
Your form is just fine.
Nov 14 '05 #3
On Sun, 29 Feb 2004 20:14:52 -0800, Ben Pfaff <bl*@cs.stanford.edu> wrote:
ro**@zworg.com (Amarendra GODBOLE) writes:
memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);


Your informant is wrong. No such casts are necessary in C.


To be more specific, no casts are required to convert any pointer type to
or from void *.

Cheers,
--
Greg.

Nov 14 '05 #4
ro**@zworg.com (Amarendra GODBOLE) wrote:
The linux manpage for memcpy(3) gives me the following prototype of
memcpy(3):
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n); memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);


That someone is wrong. Unlike, for example, C++, the C language does not
require the casts. IMO, this is a point where C is clearly superior.

Richard
Nov 14 '05 #5
Greg Barron <gr*********@bigfoot.NOGARBAGE.com> writes:
On Sun, 29 Feb 2004 20:14:52 -0800, Ben Pfaff <bl*@cs.stanford.edu> wrote:
ro**@zworg.com (Amarendra GODBOLE) writes:
memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);


Your informant is wrong. No such casts are necessary in C.


To be more specific, no casts are required to convert any pointer type
to or from void *.


That only applies to pointers to objects, but not to function pointers.
The latter cannot be converted to `void *' (or vice versa) at all.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #6
Martin Dickopp wrote:

Greg Barron <gr*********@bigfoot.NOGARBAGE.com> writes:
On Sun, 29 Feb 2004 20:14:52 -0800,
Ben Pfaff <bl*@cs.stanford.edu> wrote:
ro**@zworg.com (Amarendra GODBOLE) writes:

memcpy(arr, p, sizeof *p);

Someone tells me
-- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);

Your informant is wrong. No such casts are necessary in C.


To be more specific,
no casts are required to convert any pointer type
to or from void *.


That only applies to pointers to objects,
but not to function pointers.
The latter cannot be converted to `void *' (or vice versa) at all.


A cast is required when converting from (const void *) to (void *).

--
pete
Nov 14 '05 #7
[snips]

On Mon, 01 Mar 2004 11:00:48 +0000, pete wrote:
A cast is required when converting from (const void *) to (void *).


This should, in all likelihood, simply not be done in the first place. :)
Nov 14 '05 #8
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
ro**@zworg.com (Amarendra GODBOLE) wrote:
The linux manpage for memcpy(3) gives me the following prototype of
memcpy(3):
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

memcpy(arr, p, sizeof *p);

Someone tells me -- this is an incorrect usage, you either need to do
memcpy(arr, (char *)p, sizeof *p);
or
memcpy((void *)arr, (void *)p, sizeof *p);


That someone is wrong. Unlike, for example, C++, the C language does not
require the casts. IMO, this is a point where C is clearly superior.


As I read the C++ standard, C++ requires a cast to convert from
void * to pointer-to-object type, but not to convert from
pointer-to-object type to void *. I am willing to be corrected
on this point.
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Nov 14 '05 #9
"Richard Bos" <rl*@hoekstra-uitgeverij.nl> wrote in message
news:40**************@news.individual.net...
Unlike, for example, C++, the C language does not
require the casts. IMO, this is a point where C is clearly superior.


Another one is readability ;-)
Nov 14 '05 #10

In article <pa****************************@lightspeed.bc.ca >, Kelsey Bjarnason <ke*****@lightspeed.bc.ca> writes:
On Mon, 01 Mar 2004 11:00:48 +0000, pete wrote:
A cast is required when converting from (const void *) to (void *).


This should, in all likelihood, simply not be done in the first place. :)


There are times when it is (IMO) appropriate. I often find myself
dealing with APIs supplied by another developer that are not const-
correct - that is, they don't declare object-pointer parameters to
data they do not change as const. When I wrap such a function in one
of my own, mine will be const-correct. At some point, then, I may
have to pass a pointer to a const object as a pointer to a non-const
object. That's going to require a const-removing cast somewhere.

(The alternatives that come to mind are copying the data into a new
area and passing a non-const pointer to it, and getting the API owner
to fix his API. The former is obviously less than optimal. The
latter is preferable but not always achievable in a reasonable
timeframe.)

--
Michael Wojcik mi************@microfocus.com

Be sure to push the button of the bottom, and push the button of the
settlement page indicated next only once, there is fear of the bottom
rhinoceros multiplex lesson money. -- Sukebe Net
Nov 14 '05 #11
Ben Pfaff <bl*@cs.stanford.edu> wrote in message:
Your informant is wrong. No such casts are necessary in C.


Thanks all of you. All the replies have made my stand strong, and I
can prove my point now. But this cannot be end without a small joke...

I wrote a code snippet for my colleague: (the ``someone'' in my
previous post.) :)

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

int main(void)
{
char arr[20];
typedef struct foo_ {
int i;
char c;
float f;
} foo;
foo *fptr;
foo *fptr1;

/* Okay, in real life we need to check the return value of
malloc() */
fptr = malloc(sizeof *fptr);
fptr->i = 21;
fptr->c = 'A';
fptr->f = 16.45;

memcpy(arr, fptr, sizeof *fptr);
fptr1 = (foo *)arr;

printf("Array contains %i, %c, %f\n", fptr1->i, fptr1->c,
fptr1->f);
free(fptr);

return 0;
}

I do get correct values printed out. Even after this, my colleague
told me that it has worked here because foo is a simple stucture, and
it might not work in complicated structures (!). Never heard that C --
makes a distinction between simple and complex structures !! ;)

Thanks once again.

Cheers,
Amarendra

--
Picture Perfect Engineering / GE Security / #include
<std$disclaimer.h>
Nov 14 '05 #12
On 1 Mar 2004 18:43:45 -0800,
Amarendra GODBOLE <ro**@zworg.com> wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote in message:
Your informant is wrong. No such casts are necessary in C.

I wrote a code snippet for my colleague: (the ``someone'' in my
previous post.) :) foo *fptr;
foo *fptr1; memcpy(arr, fptr, sizeof *fptr);
fptr1 = (foo *)arr;
You also don't need, and shouldn't use, this cast.
I do get correct values printed out. Even after this, my colleague
told me that it has worked here because foo is a simple stucture, and
it might not work in complicated structures (!). Never heard that C --
makes a distinction between simple and complex structures !! ;)


Your collegue is still wrong. If he means that you can't simply use
memcpy() to make a 'deep' copy of a structure that has pointers in iti
(which could be one interpretation of 'complicated' structures),
he/she is right, but that won't be fixed with a cast.

The point is simply that casts are not necessary in memcpy() (or
anywhere else where pointers need to be converted to void * or from
void *). The complexity of whatever is being pointed to does not
change that in any way. Maybe your collegue could explain what
"complicated structures" are?

Martien
--
|
Martien Verbruggen | Begin at the beginning and go on till you
Trading Post Australia | come to the end; then stop.
|
Nov 14 '05 #13
Amarendra GODBOLE wrote:
Ben Pfaff <bl*@cs.stanford.edu> wrote in message:
Your informant is wrong. No such casts are necessary in C.


Thanks all of you. All the replies have made my stand strong, and I
can prove my point now. But this cannot be end without a small joke...

I wrote a code snippet for my colleague: (the ``someone'' in my
previous post.) :)

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

int main(void)
{
char arr[20];
typedef struct foo_ {
int i;
char c;
float f;
} foo;
foo *fptr;
foo *fptr1;

/* Okay, in real life we need to check the return value of
malloc() */
fptr = malloc(sizeof *fptr);
fptr->i = 21;
fptr->c = 'A';
fptr->f = 16.45;

memcpy(arr, fptr, sizeof *fptr);
fptr1 = (foo *)arr;

printf("Array contains %i, %c, %f\n", fptr1->i, fptr1->c,
fptr1->f);
free(fptr);

return 0;
}

I do get correct values printed out. Even after this, my colleague
told me that it has worked here because foo is a simple stucture, and
it might not work in complicated structures (!). Never heard that C --
makes a distinction between simple and complex structures !! ;)


Wrong answer. 'Working' here actually depends on the alignment of
arr, over which you have no direct control. There are several
illegalities in your code snippet, especially including the
assignment to fptr1 and the cast involved. Ugh.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #14
In article <40***************@yahoo.com>,
CBFalconer <cb********@yahoo.com> wrote:
Wrong answer. 'Working' here actually depends on the alignment of
arr, over which you have no direct control. There are several
illegalities in your code snippet, especially including the
assignment to fptr1 and the cast involved. Ugh.


Many people who are not deterred by the plain ugliness and the fact that
there is undefined behavior (which means even if it "works" today, it
can fail if you compile it again with the next compiler version, with an
optimising compiler, with a different compiler, on a different
architecture), might be deterred by the fact that using unaligned
pointer might easily make your code run fifty times slower than it
could.
Nov 14 '05 #15
> > memcpy(arr, fptr, sizeof *fptr);
fptr1 = (foo *)arr;
Wrong answer. 'Working' here actually depends on the alignment of
arr, over which you have no direct control. There are several
illegalities in your code snippet, especially including the
assignment to fptr1 and the cast involved. Ugh.


Hmmm...yes, right you are. How do I get the values back then ? Will
you kindly point out the other illegalities too ? Thanks in advance.

Cheers,
Amarendra

--
Be ashamed to die unless you have won some victory for humanity.
-Horace Mann
Nov 14 '05 #16
Amarendra GODBOLE wrote:
memcpy(arr, fptr, sizeof *fptr);
fptr1 = (foo *)arr;

Wrong answer. 'Working' here actually depends on the alignment of
arr, over which you have no direct control. There are several
illegalities in your code snippet, especially including the
assignment to fptr1 and the cast involved. Ugh.


Hmmm...yes, right you are. How do I get the values back then ? Will
you kindly point out the other illegalities too ? Thanks in advance.


The size issue can be addressed by using the sizeof result
from the structure, to allocate the array.
The alignment issue can be addressed by a union,
as in K&R2 Section 8.7, Example-A Storage Allocator.

/* BEGIN memcast.c */

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

int main(void)
{
struct foo {
int i;
char c;
float f;
};
union {
char arr[sizeof(struct foo)];
struct foo align;
} align;
struct foo struct1;
struct foo *fptr1;

struct1.i = 21;
struct1.c = 'A';
struct1.f = 16.45f;
memcpy(align.arr, &struct1, sizeof struct1);
fptr1 = (struct foo *)align.arr;
printf("Array contains %i, %c, %f\n",
fptr1 -> i, fptr1 -> c, fptr1 -> f);
return 0;
}

/* END memcast.c */
--
pete
Nov 14 '05 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: hs | last post by:
Is the following correct? void foo(int len, char* val) { .. .. .. unsigned char* string = (unsigned char*) new char ; memcpy(string, val, len); ..
2
by: Paul Schouten | last post by:
Hey, Currently im working on a project where a dynamic database is created in memory, the database can be of any size both in the amount of rows aswell as in the amount of columns. The database...
36
by: Olga Sayenko | last post by:
Hi, I am trying to make sure that my data doesn't show up anywhere outside my process unencrypted. I am concerned that if I use memcpy, the bytes copied will end up in some memory somewhere...
9
by: gvarndell | last post by:
Hi, In the following code fragment, gcc seems to ignore the initial value assigned to pData. (compiled -fvolatile -O2 with gcc) void test(void) { void *pData = (void*)0x3400; pData =...
6
by: myhotline | last post by:
hi all im very confused about using memcpy and i have three questions....memcpy takes a pointer to src and a pointer to dest and copies src to destination...but im very confuzed about when to...
7
by: James Mcguire | last post by:
Hi, I frequently do non-initialisation type structure assignment via casting: e.g. struct s{int i,j,k;} mys; .... mys=(struct s){3,4,5};
39
by: Martin Jørgensen | last post by:
Hi, I'm relatively new with C-programming and even though I've read about pointers and arrays many times, it's a topic that is a little confusing to me - at least at this moment: ---- 1)...
2
by: murat.migdisoglu | last post by:
hi, while i was browsing some codes, i've seen multiple times casting the return value of memcpy function to void. ( ......; ......; (void)memcpy(.......); .....; )
18
by: Mark | last post by:
Hi List, I want to write a function to copy some data out of a hardware buffer. The hardware can change the contents of this buffer without it being written to by my function. I want to use...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.