Sunday 13 November 2011

What standard functions are available to manipulate memory? in C programming

What standard functions are available to manipulate memory?

Several functions copy, compare, and fill arbitrary memory. These functions take void* (pointers to nothing in particular); they work with pointers to anything.

There are two functions (roughly like strncpy) for copying information. One, memmove, copies memory from one place to another, even if the two places overlap. Why is that important? Say you have a buffer with some data already in it, and you want to move it “to the right” to make room at the beginning of the buffer.  Listing XII.6 shows a program that tries to perform this action but doesn’t do it right.

A program that tries to move data but trashes it instead.

static char buf[] =
{‘R’, ‘I’, ‘G’, ‘H’, ‘T’, ‘\0’, ‘-’, ‘-’, ‘-’};
int
main()
{
int i;
for (i=0; i<6; ++i) {
buf[i+3] = buf[i];
}
}
The idea was to change buf from being “RIGHT” to being “RIGRIGHT” so that other data could be put in the first three bytes. Unfortunately, that’s not what happened. If you unroll the for loop (or run the progra with a debugger to see what it’s doing), you’ll see that the program really acted like this:

buf[3] = buf[0];
buf[4] = buf[1];
buf[5] = buf[2];
buf[6] = buf[3];
buf[7] = buf[4];
buf[8] = buf[5];
buf[9] = buf[6];
The effect on the data is shown in Figure XII.6a (the newly copied data is shown in bold). The program trashed some of the data it was supposed to move!




The purpose for explaining all that is to tell you this: the memmove function knows that rule. It is guaranteed to copy data, even overlapping data, the right way. If you’re copying or moving data and you’re not sure whether the source and destination overlap, use memmove. If you’re sure they don’t overlap, memcpy might be marginally faster.

The memcmp function is like the strncmp function, except that it doesn’t stop at bytes with NUL characters (‘\0’). It shouldn’t be used to compare struct values, though. Say that you have the following structure:

struct foo {
short s;
long l;
}

And say that on the system your program will run on, a short is two bytes (16 bits) long, and a long is four bytes (32 bits) long. On a 32-bit machine, many compilers put two bytes of “junk” between s and l so that l starts on a word boundary. If your program runs on a little-endian machine (the least significant byte is stored at the lowest address), the structure might be laid out like this:
struct foo byte[0] least significant byte of s
struct foo byte[1] most significant byte of s
struct foo byte[2] junk (make l start on a long boundary)
struct foo byte[3] junk (make l start on a long boundary)
struct foo byte[4] least significant byte of l
struct foo byte[5] second least significant byte of lstruct
struct foo byte[6] second most significant byte of l
struct foo byte[7] most significant byte of l

Two struct foos with the same s and l values might not compare equal with memcmp, because the “junk” might be different. memchr is like strchr, but it looks for a character anywhere in a specified part of memory; it won’t stop at the first NUL byte. memset is useful even for nonparanoid C programmers. It copies some byte into a specified part of memory. One common use is to initialize some structure to all zero bytes. If p is a pointer to a struct, then memset(p, ‘\0’, sizeof *p); overwrites the thing p points to with zero (NUL or ‘\0’) bytes. (This also overwrites any “junk” used to get members on word boundaries, but that’s OK; it’s junk, nobody cares what you write there.)

Cross Reference:

VI.1: What is the difference between a string copy (strcpy) and a memory copy (memcpy)? When
should each be used?
VI.3: How can I remove the leading spaces from a string?
IX.9: What is the difference between a string and an array?



No comments:

Post a Comment