473,503 Members | 12,383 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

memcpy broken?

A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).

Using our own function like this:

void MemCopy(void* dest, void* src, size_t sz)
{
unsigned char* t = dest;
unsigned char* s = src;

while (sz--)
*t++ = *s++;
}

DOES work. To us, the system memcpy looks broken. Any other opinions on
why the memcpy version wouldn't work?

Thanks for any ideas,

Peter

Nov 15 '05 #1
11 2004
"Peter Pichler" <pi*****@pobox.sk> wrote in message
news:42**********@mk-nntp-2.news.uk.tiscali.com...
A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).


I don't know why it can be not working... Is it the only standard C library
function that looks like not working?
Is the memcpy function inlined or not?
Also, what if you change sizeof t to sizeof(t)?
Do you #include <string.h>?
If you use gcc, what's the corresponding asm output (use the -S switch to
translate .c source into asm source).

Alex
Nov 15 '05 #2
Alexei A. Frounze wrote on 31/07/05 :
Also, what if you change sizeof t to sizeof(t)?


Won't change anything (unless the implementation is seriously broken)

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Mal nommer les choses c'est ajouter du malheur au
monde." -- Albert Camus.
Nov 15 '05 #3
Alexei A. Frounze wrote:
Do you #include <string.h>?


Gotcha! To be honest, I don't know. It didn't occur to me to ask,
assuming that the colleague knew what he was doing. I will have to check
on Monday.

Peter

Nov 15 '05 #4
Peter Pichler wrote:
A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).

Using our own function like this:

void MemCopy(void* dest, void* src, size_t sz)
{
unsigned char* t = dest;
unsigned char* s = src;

while (sz--)
*t++ = *s++;
}

DOES work. To us, the system memcpy looks broken. Any other opinions on
why the memcpy version wouldn't work?


Apart from Alexei A. Frounze's reply:
It can go wrong if the memory areas overlap -- only memmove() is
guaranteed to work with overlapping source and destination storage.
Your implementation of MemCopy() could, e.g., deal with s = t+1.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #5
Michael Mair wrote:
Peter Pichler wrote:
void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
} <snip> Any other opinions on why the memcpy version wouldn't work?


Apart from Alexei A. Frounze's reply:
It can go wrong if the memory areas overlap -- only memmove() is
guaranteed to work with overlapping source and destination storage.
Your implementation of MemCopy() could, e.g., deal with s = t+1.


I had thought about that. I don't think it applies here, though. We pass
THING to the function, not its address, thus copying it to a temporary
storage. Overlapping is unlikely to happen. Thanks for the idea anyway.

Peter

Nov 15 '05 #6
"Peter Pichler" <pi*****@pobox.sk> wrote in message
news:42**********@mk-nntp-2.news.uk.tiscali.com...
....
I had thought about that. I don't think it applies here, though. We pass
THING to the function, not its address, thus copying it to a temporary
storage. Overlapping is unlikely to happen. Thanks for the idea anyway.


Btw, do you enable all warnings (for gcc: -Wall)? Any suspicious warnings?

Alex
Nov 15 '05 #7
Peter Pichler wrote:
A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).

Using our own function like this:

void MemCopy(void* dest, void* src, size_t sz)
{
unsigned char* t = dest;
unsigned char* s = src;

while (sz--)
*t++ = *s++;
}

DOES work. To us, the system memcpy looks broken. Any other opinions on
why the memcpy version wouldn't work?

Thanks for any ideas,

Peter

The original was..

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

...which is flawed because &t is the address of the function parameter,
not the real THING.

The sizeof t is also problematic if THING is other than a struct type.

Before you and your colleague agree among yourselves that Standard C
functions like memcpy() might be broken and you should tell c.l.c about
it, take a break, a deep breath and look at your code. memcpy() is at
least thirty years old. It works.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 15 '05 #8
In article <U9********************@comcast.com>,
Joe Wright <jo********@comcast.net> wrote:
The original was..

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

..which is flawed because &t is the address of the function parameter,
not the real THING.
But the parameter will be a copy of the real THING, so why would that
matter?
The sizeof t is also problematic if THING is other than a struct type.


There's a problem if t is a pointer and he means to copy what t points
to rather than t itself.

-- Richard
Nov 15 '05 #9
Peter Pichler wrote:
A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).


1. Make sure you #include <string.h> and compile with all available
warnings enabled. Lack of a memcpy prototype (coupled with no warnings
enabled or perhaps invoking the compiler in a non-compliant mode) may
cause the wrong "information" to get passed to the C library's memcpy
function.

2. In the same vein, verify the compiler is set up to use the same ABI
as the libraries you're linking against.

3. Consider avoiding passing structures by value altogether
(especially in less popular or niche embedded environments). It's been
historically a source of compiler bugs and ABI incompatibilities. It's
also unnecessarily inefficient, as it requires an extra copy of THING
to be made.
Mark F. Haigh
mf*****@sbcglobal.net

Nov 15 '05 #10
On Sun, 31 Jul 2005 08:05:56 +0100, Peter Pichler wrote:
A colleague encountered an interesting problem. Suppose we have a C
function like this:

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

to copy a THING to any byte address (which might not be aligned for a
THING, hence not doing *(THING*)addr = t).

There's a platform on which it fails, i.e. after the function the
contents of addr are not the thing written to it. (addr is an address in
a malloc'd area, hence properly aligned for THING).
Does it work if you use a copy loop such as the one below instead of
memcpy(). What if you use memmove()?
Using our own function like this:

void MemCopy(void* dest, void* src, size_t sz)
{
unsigned char* t = dest;
unsigned char* s = src;

while (sz--)
*t++ = *s++;
}
Does this version work if you use memcpy() instead of the copy loop?
DOES work. To us, the system memcpy looks broken. Any other opinions on
why the memcpy version wouldn't work?


Failure to include <string.h>, a bug somewhere else in the program
corrupting things.

Lawrence
Nov 15 '05 #11
On Sun, 31 Jul 2005 18:08:19 -0400, Joe Wright
<jo********@comcast.net> wrote:

snip
The original was..

void WRITE_THING(void* addr, THING t)
{
memcpy(addr, &t, sizeof t);
}

..which is flawed because &t is the address of the function parameter,
not the real THING.
As long as THING is not an array, the function parameter is a copy of
the real THING. Therefore, &t is the address of this copy (which must
have the same value(s) as the original) and sizeof t is the size of
either the original or the copy (since both have the same size).

The sizeof t is also problematic if THING is other than a struct type.
You think sizeof won't work if THING is int or double?

Before you and your colleague agree among yourselves that Standard C
functions like memcpy() might be broken and you should tell c.l.c about
it, take a break, a deep breath and look at your code. memcpy() is at
least thirty years old. It works.


<<Remove the del for email>>
Nov 15 '05 #12

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

Similar topics

13
17481
by: franky.backeljauw | last post by:
Hello, following my question on "std::copy versus pointer copy versus member copy", I had some doubts on the function memcpy, as was used by tom_usenet in his reply. - Is this a c++ standard...
5
3713
by: manya | last post by:
Ok, it's been a while since I've done the whole memcpy stuff with C++ and I'm having a hard time remembering everything. I hope, however, that you can help me with my problem. I memcpy a...
35
12006
by: Christopher Benson-Manica | last post by:
(if this is a FAQ or in K&R2, I didn't find it) What parameters (if any) may be 0 or NULL? IOW, which of the following statements are guaranteed to produce well-defined behavior? char src;...
33
33630
by: Case | last post by:
#define SIZE 100 #define USE_MEMCPY int main(void) { char a; char b; int n; /* code 'filling' a */
6
2903
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...
70
11538
by: Rajan | last post by:
Hi, I am trying to simulate a memcpy like this void* mem_cpy(void* dest, void* src, int bytes) { dest = malloc(bytes); } Now if I want to copy the bytes from src to dest, how do I copy these...
3
6550
by: ebrahimbandookwala | last post by:
HI everyone I am supposed to pass back a pointer to a struct from a function whos definition cannot be changed flight_t * get_item(field_t field , void * data) the problem I encounter is...
16
2774
by: Jeff | last post by:
Im trying to memcpy a buffer from a filled in simple structure. When I memcpy and then print the resulting buffer, I see 7 locations that have junk before my data starts. My data structure is: ...
6
4424
by: danu | last post by:
Basically I'm trying to do here is put the uint32_t seq_num into the first 4 bytes of the buf. But every time I do this, it wouldn't get copied in to the buf at all. Can anyone point out the...
0
7212
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
7098
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...
0
7296
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7364
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7470
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5604
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4696
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3174
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
1524
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.