473,326 Members | 2,124 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,326 software developers and data experts.

memmove() Usage

Ian
I read the FAQ about the differences between memcpy() and memmove().
Apparently memmove() is supposed to be safer. Just to make sure I
understand the concept of memmove(), can someone tell me if this
little function is using memmove() correctly?

void strdel(char *s, size_t offset, size_t count) {
if ((!s) || (offset > strlen(s)) || (count > strlen(s))) return;
memmove(s+offset,s+(count+1),strlen(s)-count);
}
The function will delete a portion of a string at the give positions.

For example:

char tmpstr[10] = "Hello";
strdel(tmpstr,0,0);

This would change "Hello" to "ello".

It appears to work correctly, but I just want to make sure I am using
memmove() correct in this case, and that the function is not open to
an overflow of some kind...

Thanks

Feb 13 '06 #1
12 3107

"Ian" <ia****@gmail.com.invalid> wrote in message
news:Wn*****************@fe01.usenetserver.com...
I read the FAQ about the differences between memcpy() and memmove().
Apparently memmove() is supposed to be safer. Just to make sure I
understand the concept of memmove(), can someone tell me if this
little function is using memmove() correctly?

void strdel(char *s, size_t offset, size_t count) {
if ((!s) || (offset > strlen(s)) || (count > strlen(s))) return;
memmove(s+offset,s+(count+1),strlen(s)-count);
}
The function will delete a portion of a string at the give positions.

For example:

char tmpstr[10] = "Hello";
strdel(tmpstr,0,0);

This would change "Hello" to "ello".

It appears to work correctly, but I just want to make sure I am using
memmove() correct in this case, and that the function is not open to
an overflow of some kind...


It is if called incorrectly (though it's not obligatory to protect all
functions against being called wrongly).

Looks like s[offset] is the first byte to delete, and s[count] is the last
byte to delete?

Then if count == offset you delete one byte, and if count == offset - 1 you
delete 0 bytes.

But if count < offset - 1 you end up moving bytes to the right, so you can
run out of space.

--
RSH


Feb 13 '06 #2
Ian
On Mon, 13 Feb 2006 09:22:53 GMT, Robin Haigh wrote:
But if count < offset - 1 you end up moving bytes to the right, so
you can run out of space.


But isn't memmove() supposed to protect that from happening? I thought
the whole purpose of memmove() was to provide a safe way to copy
memory...

The man page for memmove() says the following:

"The memmove() function copies len bytes from string src to string dst.
The two strings may overlap; the copy is always done in a non-
destructive manner."
I take that to mean no matter what offset and count is given, memmove()
is responsible for making sure that nothing goes wrong; no matter what.

Feb 13 '06 #3
Ian wrote:
I take that to mean no matter what offset and count is given,
memmove()
is responsible for making sure that nothing goes wrong;
no matter what.


All library functions do what they're supposed to do,
when you call them with correct arguments.

If you have a string in an arrray:
char array[] = "abc";
and you want to copy the third character onto the first,
so that it becomes "cbc", then you can use memcpy:

memcpy(array, array + 2, 1);
If you have a string in an arrray:
char array[] = "abc";
and you want to copy the last two characters to the
front so that it becomes "bcc", then use memmove:

memmove(array, array + 1, 2);

.... because memcpy is undefined
when the source and destination overlap.

--
pete
Feb 13 '06 #4

"Ian" <ia****@gmail.com.invalid> wrote in message
news:Uz*****************@fe31.usenetserver.com...
On Mon, 13 Feb 2006 09:22:53 GMT, Robin Haigh wrote:
But if count < offset - 1 you end up moving bytes to the right, so
you can run out of space.


But isn't memmove() supposed to protect that from happening? I thought
the whole purpose of memmove() was to provide a safe way to copy
memory...

The man page for memmove() says the following:

"The memmove() function copies len bytes from string src to string dst.
The two strings may overlap; the copy is always done in a non-
destructive manner."
I take that to mean no matter what offset and count is given, memmove()
is responsible for making sure that nothing goes wrong; no matter what.

It only means that it won't scribble over the data it's about to copy. It
doesn't know where the end of the destination buffer is, so it can't protect
itself against running off the end.

Incidentally, this manpage is using the word string more loosely than the
standard. Strings as defined have null-byte terminators, but with
memmove(), null-terminators aren't required or respected.

--
RSH
Feb 13 '06 #5
Ian wrote:
I read the FAQ about the differences between memcpy() and memmove().
Apparently memmove() is supposed to be safer. Just to make sure I
understand the concept of memmove(), can someone tell me if this
little function is using memmove() correctly?

void strdel(char *s, size_t offset, size_t count) {
if ((!s) || (offset > strlen(s)) || (count > strlen(s))) return;
memmove(s+offset,s+(count+1),strlen(s)-count);
}
May I make some suggestions about the code? First, you don't need all
those checks at the top: you can combine the last two into

offset + len > strlen(s)

which tests what you really care about: that the end of the requested
region to delete does not lie past the end of the string itself
(actually, my opinion is that you could easily "round down" if this
happens, though this has its own usage problems, which you should think
about). This makes it (marginally) faster and also easier to
understand.

Second, I think you're calling memmove() incorrectly. It's declared as

void *memmove(void *dest, void *src, size_t n);

so your first argument should be the desired destination (s + offset;
that's good) and your second should be the start of the string you're
moving (s + offset + count: you have to skip past the entire deleted
substring to the beginning of the remainder, and move that remainder
back). Finally, your third argument should be the number of characters
you move, which is not strlen(s) - count but strlen(s) - count -
offset, since you move nothing before the end of the deleted portion.
With that in mind, you should write the function as

void strdel(char *s, size_t offset, size_t count)
{
if (!s || offset + count > strlen(s))
return NULL;
memmove(s + offset, s + offset + count,
strlen(s) - count - offset);
}

Another, very subtle, error remains, which you should find before you
actually use this thing. Note that the semantics are now a little
different than yours: offset is the index of the first character to
delete (or the number of characters before it; i.e. its offset) and
count is the number of characters to delete. I didn't make that choice
consciously, however; it just came from the C string-indexing
conventions.

The function will delete a portion of a string at the give positions.

For example:

char tmpstr[10] = "Hello";
For what it's worth, there's no need to include the [10] in this
definition; the compiler will automatically construct an array of the
correct size for the string. This prevents you from accidentally
writing something less than the length of the string, too.
strdel(tmpstr,0,0);
With my version of the function, this would be

strdel(tmpstr, 0, 1);
This would change "Hello" to "ello". From looking at the function as you wrote it, it would seem that the only reason this does what you think it should is that you happen to be
deleting only one character at the beginning of the string. If you
were doing more than one character, or if it were not at the beginning,
things would go wrong. If you are going to test your functions, try to
tailor the tests to exploit the algorithm as much as they can.
It appears to work correctly, but I just want to make sure I am using
memmove() correct in this case, and that the function is not open to
an overflow of some kind...


As others have pointed out, memmove() does not protect against
overflow; it merely ensures that if you are reading from and writing to
the same memory locations, data is not destroyed before the location it
occupies is read from. The sort of thing that might happen with a
quick-and-dirty implementation of memcpy() is that you call it such:

char str[] = "Hello";
memcpy(str + 1, str, 4);

and end up with "HHHHH" in str, because the function would read the
first character and write it in the second, then read the second (which
is now 'H' rather than 'e') and write it in the third, etc. memmove()
is more careful than this.

--
Ryan Reich
ry********@gmail.com

Feb 14 '06 #6
Ian
On Tue, 14 Feb 2006 01:44:06 GMT, Ryan Reich wrote:
With that in mind, you should write the function as

void strdel(char *s, size_t offset, size_t count)
{
if (!s || offset + count > strlen(s))
return NULL;
memmove(s + offset, s + offset + count,
strlen(s) - count - offset);
}

I tested the function, but it doesn't seem to work correctly.

Let's use this string as an example:

char string[] = "racecar";
Using your function like this:

strdel(string,0,3);

should've turned "racecar" into "car", but it didn't.

My functions seems to work correctly for this test, but I'm not sure
why. memmove() is really confusing me...

Feb 14 '06 #7
Ian wrote:
On Tue, 14 Feb 2006 01:44:06 GMT, Ryan Reich wrote:
With that in mind, you should write the function as

void strdel(char *s, size_t offset, size_t count)
{
if (!s || offset + count > strlen(s))
return NULL;
This NULL shouldn't be there, since the function returns type void.
The compiler might complain, though it's probably harmless if it
actually compiles.
memmove(s + offset, s + offset + count,
strlen(s) - count - offset);
}

I tested the function, but it doesn't seem to work correctly.

Let's use this string as an example:

char string[] = "racecar";
Using your function like this:

strdel(string,0,3);

should've turned "racecar" into "car", but it didn't.

My functions seems to work correctly for this test, but I'm not sure
why. memmove() is really confusing me...


Perchance, is it instead giving you "ecarcar"? Because that's what it
gives me when I test your example. This is exactly what I expected it
to produce, though not what you did. It also perfectly illustrates the
subtle error I mentioned before. Think about it (hint: think about how
C represents strings). Also, if you wanted "car", you should have
called the function as

strdel(string, 0, 4);

to delete the first four characters, "race".

--
Ryan Reich
ry********@gmail.com

Feb 14 '06 #8
Ian
On Tue, 14 Feb 2006 03:15:54 GMT, Ryan Reich wrote:
Perchance, is it instead giving you "ecarcar"? Because that's
what it gives me when I test your example. This is exactly what I
expected it to produce, though not what you did. It also
perfectly illustrates the subtle error I mentioned before. Think
about it (hint: think about how C represents strings). Also, if
you wanted "car", you should have called the function as

strdel(string, 0, 4);

to delete the first four characters, "race".


Using your example: strdel(string,0,4) gives me "carecar". I tested
this both on Digital Mars and Borland compilers in ANSI C mode. They
both do the same.

Feb 14 '06 #9

Ian wrote:
On Tue, 14 Feb 2006 03:15:54 GMT, Ryan Reich wrote:
Perchance, is it instead giving you "ecarcar"? Because that's
what it gives me when I test your example. This is exactly what I
expected it to produce, though not what you did. It also
perfectly illustrates the subtle error I mentioned before. Think
about it (hint: think about how C represents strings). Also, if
you wanted "car", you should have called the function as

strdel(string, 0, 4);

to delete the first four characters, "race".


Using your example: strdel(string,0,4) gives me "carecar". I tested
this both on Digital Mars and Borland compilers in ANSI C mode. They
both do the same.


Well, I don't expect it to depend on the compiler. You still haven't
found the error in my function, though. Ask yourself: what sort of
error could lead to the string having extra characters at the end?

--
Ryan Reich
ry********@gmail.com

Feb 14 '06 #10
maybe is:
memmove(s + offset, s + offset + count + 1, strlen(s) - offset - count
-1);

Feb 15 '06 #11
zh*****@yahoo.com.cn wrote:
maybe is:
memmove(s + offset, s + offset + count + 1, strlen(s) - offset - count
-1);


It's difficult to tell what you are talking about (see below).

Brian

--
Please quote enough of the previous message for context. To do so from
Google, click "show options" and use the Reply shown in the expanded
header.
Feb 15 '06 #12
Ian wrote:
is this little function using memmove() correctly?

void strdel(char *s, size_t offset, size_t count) {
if ((!s) || (offset > strlen(s)) || (count > strlen(s))) return;
memmove(s+offset,s+(count+1),strlen(s)-count);
}


I know I'm not answering your question; just wanted to point out that
"strdel" is reserved for the implementation as is any identifier that
starts with "str" and is followed by a lowercase letter (and maybe a few
more).

--
If you're posting through Google read <http://cfaj.freeshell.org/google>
Feb 15 '06 #13

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

Similar topics

2
by: rinku24 | last post by:
What is the difference between memcpy and memmove? Which is more expensive?
71
by: ROSY | last post by:
1. How would you use the functions memcpy(), memset(), memmove()?
21
by: Mac | last post by:
$ cat junk27.c #include <stdio.h> #include <string.h> int main (void) { printf("The difference between memcpy and memmove is %ld\n", (long int) memcpy - (long int) memmove); return 0; }
21
by: Method Man | last post by:
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...
6
by: novice | last post by:
Please explain with an example whts the DIFFERENCE between "memcpy" and "memmove"
1
by: kyo guan | last post by:
Hi : python list object like a stl vector, if insert a object in the front or the middle of it, all the object after the insert point need to move backward. look at this code ( in python...
5
by: xdevel | last post by:
Hi, anyone can make me an example where memmove does not cause a memory overlapping and where memcpy do it? Thanks
14
by: somenath | last post by:
Hi All, I am trying to understand the behavior of the memcpy and memmove. While doing so I wrote a program as mentioned bellow . #include<stdio.h> #include<stdlib.h> #include<string.h> ...
3
by: Chris | last post by:
Hello all, Not sure if this is off topic, if it is I apologise in advance. Is it safe to use memmove() on an array of objects? I create an array of Objects and I have a cursor to indicate...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.