Questions about memmove

M

Method Man

Just a few theoretical questions I had on 'memmove':

1. Is there ever a good reason to use memcpy instead of memmove?
2. Is memmove useful to copy structs (as opposed to = operator)?
3. In general, when should memmove explicitly be used? [I have only seen it
used in code to copy char arrays and even then, <string.h> provides most of
the necessary functionality.]
 
T

Thomas Matthews

Method said:
Just a few theoretical questions I had on 'memmove':

1. Is there ever a good reason to use memcpy instead of memmove?
Yes, when the source and destination do not overlap.
The memcpy function may be more efficient since it doesn't have
to be as careful as memmove.

2. Is memmove useful to copy structs (as opposed to = operator)?
As long as the structs do not contain pointers or instances of
structures (which may contain pointers). With pointers, one
runs into ownership and duplication issues.

3. In general, when should memmove explicitly be used? [I have only seen it
used in code to copy char arrays and even then, <string.h> provides most of
the necessary functionality.]
The function memmove should explicity be used when the source and
destination locations overlap.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book
http://www.sgi.com/tech/stl -- Standard Template Library
 
M

Malcolm

Method Man said:
1. Is there ever a good reason to use memcpy instead of memmove?
Yes, it makes your intentions clearer if memmove() is reserved for
potentially overlapping regions. Also it may be more efficient to call
memcpy().
2. Is memmove useful to copy structs (as opposed to = operator)?
Use memcpy() for this. Personally I dislike the = operator applied to struct
assignments, since it fails to make clear that this may be an expensive
operation. To people used to other languages, it also fails to make it
obvious that this is a "shallow copy".
3. In general, when should memmove explicitly be used? [I have only seen it
used in code to copy char arrays and even then, <string.h> provides most of
the necessary functionality.]
Let's say we have an array of objects, and we want to insert an item in the
middle. The items at the end are unused, because the array capacity is
bigger than the actual contents. By calling memove we can move all items up
by one, and then insert our entry.
Since this operation is expensive, it is not used all that often (if you
expect a lot of inserts, you would use a tree or a linked list instead). But
it is still useful on occasions.
 
P

pete

Method said:
Just a few theoretical questions I had on 'memmove':

1. Is there ever a good reason to use memcpy instead of memmove?

If you're copying between nonoverlapping regions of memory.
2. Is memmove useful to copy structs (as opposed to = operator)?

I prefer the assignment operator for stucture copying.
It gives the compiler an oportunity to accomplish the deed
whichever way is best.
If your structure has just a few int type members,
then a structure assignment,
might translate into just a few int assignment instructions.
3. In general, when should memmove explicitly be used?
[I have only seen it used in code to copy char arrays and even then,
<string.h> provides most of the necessary functionality.]

memmove is a string function. What do you mean by
"<string.h> provides most of the necessary functionality."?
 
K

Keith Thompson

pete said:
Method Man wrote: [...]
3. In general, when should memmove explicitly be used?
[I have only seen it used in code to copy char arrays and even then,
<string.h> provides most of the necessary functionality.]

memmove is a string function. What do you mean by
"<string.h> provides most of the necessary functionality."?

memmove isn't what I would call a string function, even though it's
declared in <string.h>. It operates on arrays of characters, not on
strings. (A string, by definition, is terminated by a nul character.)
 
P

pete

Keith said:
pete said:
Method Man wrote: [...]
3. In general, when should memmove explicitly be used?
[I have only seen it used in code to copy char arrays and even then,
<string.h> provides most of the necessary functionality.]

memmove is a string function. What do you mean by
"<string.h> provides most of the necessary functionality."?

memmove isn't what I would call a string function,
even though it's declared in <string.h>.

I think that's sufficient to make it a string function.
Both char * and void * arguments are mentioned in the section
of the standard which is labeled "String function conventions".
void * arguments don't apply to any of the string functions
which take pointers to strings as arguments.
 
M

Method Man

2. Is memmove useful to copy structs (as opposed to = operator)?
As long as the structs do not contain pointers or instances of
structures (which may contain pointers). With pointers, one
runs into ownership and duplication issues.

Could you elaborate on this point for me?

Since pointers are just addresses, I don't see why it would be a problem to
copy struct pointers over using 'memmove'. What are the ownership and
duplication issues? I can understand the copying issue with having an
instance of a struct within a struct.

In cases where structs contain a pointer or instance of another struct, what
_would_ happen if memmove was called?
 
M

Method Man

memmove is a string function. What do you mean by
"<string.h> provides most of the necessary functionality."?

For example, using strcpy or strncpy vs. using memmove to copy char arrays.
 
M

Malcolm

Method Man said:
Since pointers are just addresses, I don't see why it would be a problem to
copy struct pointers over using 'memmove'. What are the ownership and
duplication issues? I can understand the copying issue with having an
instance of a struct within a struct.

(Untested)

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

typedef struct
{
char *name;
} EMPLOYEE;

EMPLOYEE *employee(const char *name);
void killemployee(EMPLOYEE *emp);


int main(void)
{
EMPLOYEE *emp;
EMPLOYEE *copy;

emp = employee("Fred Bloggs");
copy = employee("Bill Gates");

if(!emp || ! copy)
exit(EXIT_FAILURE);

memmove(copy, emp, sizeof(EMPLOYEE));

killemployee(emp);

printf("Employee left = %s\n", copy->name);

killemployee(copy);

return 0;

}

EMPLOYEE *employee(const char *name)
{
EMPLOYEE *answer;

answer = malloc(sizeof(EMPLOYEE));
if(answer)
{
answer->name = malloc( strlen(name) + 1);
if(!answer->name)
{
free(answer);
return 0;
}
strcpy(answer>name, name));
}

return answer;
}

void killemployee(EMPLOYEE *emp)
{
emp->name[0] = 'X'; /* shred garbage */
free(emp->name);
free(emp);
}
 
J

James Dow Allen

Malcolm said:
Use memcpy() for this. Personally I dislike the = operator applied to struct
assignments, since it fails to make clear that this may be an expensive
operation. To people used to other languages, it also fails to make it
obvious that this is a "shallow copy".

Yes (though another reason to call attention to structure copy besides
its possible expense, is that it may "alter data in a significant way"
that "=" usually doesn't).

Long long ago, my program failed to read consecutive disk sectors without
"slipping a rev"; there was a lot of cache-checking code, etc. but the
culprit was just an innocuous-looking " sector %= secs_per_trk; "
Obviously I would have noticed and fixed this computational bottleneck
much sooner if the / and % operators were replaced with
"do_a_time_consuming_divide()"

James
 
K

Keith Thompson

Method Man said:
For example, using strcpy or strncpy vs. using memmove to copy char arrays.

If the data you're copying is a counted array of characters, with '\0'
characters considered part of the data, use memmove or memcpy. If
it's a string, terminated by the first '\0' character, use strcpy or
strncpy. The mem* functions and the str* functions work on two
different kinds of data; they're not interchangeable.
 
R

Robert Harris

Keith said:
If the data you're copying is a counted array of characters, with '\0'
characters considered part of the data, use memmove or memcpy. If
it's a string, terminated by the first '\0' character, use strcpy or
strncpy. The mem* functions and the str* functions work on two
different kinds of data; they're not interchangeable.
No they are not. If you know the length of a string, then memcpy is
usually faster than strcpy and strncpy.

memmove is the only standard function that allows the source and
destination to overlap.
 
P

pete

Keith said:
The mem* functions and the str* functions work on two
different kinds of data; they're not interchangeable.

I disagree. The strcmp and strncmp functions,
both interpret the characters as unsigned char,
just like memcmp does.
 
F

Flash Gordon

I disagree. The strcmp and strncmp functions,
both interpret the characters as unsigned char,
just like memcmp does.

However, how they interpret a 0 is rather different.

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

int main (void)
{
char fred[] = { 1,0,2 };
char derf[] = { 1,0,0 };

printf("strcmp gives %d\n",strcmp(fred,derf));
printf("memcmp gives %d\n",memcmp(fred,derf,3));
return 0;
}
 
G

Gordon Burditt

2. Is memmove useful to copy structs (as opposed to = operator)?
As long as the structs do not contain pointers or instances of
structures (which may contain pointers). With pointers, one
runs into ownership and duplication issues.

What "ownership and duplication issues" would using memmove() to
copy structs containing pointers have that copying them with =
would NOT have?

Yes, you'll have trouble if you free() the pointer in one of the
structs and then expect the other one to point at valid data.
That happens regardless of the method used to copy.

Gordon L. Burditt
 
M

Method Man

Malcolm said:
Method Man said:
Since pointers are just addresses, I don't see why it would be a problem to
copy struct pointers over using 'memmove'. What are the ownership and
duplication issues? I can understand the copying issue with having an
instance of a struct within a struct.

(Untested)

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

typedef struct
{
char *name;
} EMPLOYEE;

EMPLOYEE *employee(const char *name);
void killemployee(EMPLOYEE *emp);


int main(void)
{
EMPLOYEE *emp;
EMPLOYEE *copy;

emp = employee("Fred Bloggs");
copy = employee("Bill Gates");

if(!emp || ! copy)
exit(EXIT_FAILURE);

memmove(copy, emp, sizeof(EMPLOYEE));

killemployee(emp);

printf("Employee left = %s\n", copy->name);

killemployee(copy);

return 0;

}

EMPLOYEE *employee(const char *name)
{
EMPLOYEE *answer;

answer = malloc(sizeof(EMPLOYEE));
if(answer)
{
answer->name = malloc( strlen(name) + 1);
if(!answer->name)
{
free(answer);
return 0;
}
strcpy(answer>name, name));
}

return answer;
}

void killemployee(EMPLOYEE *emp)
{
emp->name[0] = 'X'; /* shred garbage */
free(emp->name);
free(emp);
}

Thanks, I understand the problem.

Now change the line 'memmove(copy, emp, sizeof(EMPLOYEE));' to 'copy =
emp;'. Wouldn't you see the same ownership problem? The difference between
copying structs using memmove vs using =, is what I was orignally interested
in knowing.
 
D

Dan Pop

In said:
strncpy. The mem* functions and the str* functions work on two
different kinds of data; they're not interchangeable.

Not entirely true: str* functions can be trivially implemented with mem*
functions. If you know the length of the string to be copied and the
operation is in the program's performance critical path, memcpy (and
setting the null character by hand) is likely to be faster than strcpy,
especially if dealing with long strings.

Dan
 
D

Dan Pop

In said:
I disagree. The strcmp and strncmp functions,
both interpret the characters as unsigned char,
just like memcmp does.

Yet, they still have different semantics. Compare the behaviour on
the following pair of input string literals: "abcde\0fgh" and "abcde\0fgi"
when n == 9.

Dan
 
F

Flash Gordon

On Sun, 3 Oct 2004 19:18:04 -0400

Now change the line 'memmove(copy, emp, sizeof(EMPLOYEE));' to 'copy =
emp;'. Wouldn't you see the same ownership problem? The difference
between copying structs using memmove vs using =, is what I was
orignally interested in knowing.

The differences I can see are that:
1) memmove/memcpy will copy any padding, whereas using = anything could
happen with the padding.
2) the compiler might be able to do clever tricks on the basis that it
knows it is copying a structure.
3) if the compiler doesn't inline memcpy/memmove then these will involve
the overhead of a function call.
4) You could pass a pointere to memcpy/memmove to another function or
store it in a variable, obviously you can't pass a pointer to the =
operator to a function! This is possibly relevant if you are
implementing a scripting language in C.
 
K

Keith Thompson

Flash Gordon said:
On Sun, 3 Oct 2004 19:18:04 -0400



The differences I can see are that:
1) memmove/memcpy will copy any padding, whereas using = anything could
happen with the padding.

Agreed, and this could be relevant if you later try to compare the
structures using memcmp().
2) the compiler might be able to do clever tricks on the basis that it
knows it is copying a structure.

The compiler is more likely to be able to do clever tricks with an
assignment than with memmove/memcpy, but since they're part of the
standard library the compiler could still do clever tricks even with
the function calls.
3) if the compiler doesn't inline memcpy/memmove then these will involve
the overhead of a function call.

An assignment could also be implemented as a function call.

The smarter the compiler, the less difference there is (at least
potentially) between memcpy() and assignment.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,147
Messages
2,570,833
Members
47,377
Latest member
MableYocum

Latest Threads

Top