Archive | January, 2011

c training – implement memmov() function

MEMMOV Function implementation :

Implement the memmove() function. What is the difference between the memmove() and memcpy() function?

One more most frequently asked interview question!.

memmove() offers guaranteed behavior if the source and destination arguments overlap. memcpy() makes no such guarantee, and may therefore be more efficient to implement. It’s always safer to use memmove().

Note that the prototype of memmove() is …


void *memmove(void *dest, const void *src, size_t count);

Here is an implementation..

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

void *mymemmove(void *dest, const void *src, size_t count);


int main(int argc, char* argv[])
{
char *p1, *p2;
char *p3, *p4;
int  size;

printf("\n--------------------------------\n");

/* ----------------------------------------
*
* CASE 1 : From (SRC) < To (DEST)
*
*     +--+---------------------+--+
*     |  |                     |  |
*     +--+---------------------+--+
*     ^  ^
*     |  |
*   From To
*
* --------------------------------------- */

p1 = (char *) malloc(12);
memset(p1,12,'\0');
size=10;

strcpy(p1,"ABCDEFGHI");

p2 = p1 + 2;

printf("\n--------------------------------\n");
printf("\nFrom (before) = [%s]",p1);
printf("\nTo (before)   = [%s]",p2);

mymemmove(p2,p1,size);

printf("\n\nFrom (after) = [%s]",p1);
printf("\nTo (after)   = [%s]",p2);

printf("\n--------------------------------\n");

/* ----------------------------------------
*
* CASE 2 : From (SRC) > To (DEST)
*
*     +--+---------------------+--+
*     |  |                     |  |
*     +--+---------------------+--+
*     ^  ^
*     |  |
*    To From
*
* --------------------------------------- */

p3 = (char *) malloc(12);
memset(p3,12,'\0');
p4 = p3 + 2;

strcpy(p4, "ABCDEFGHI");

printf("\nFrom (before) = [%s]",p4);
printf("\nTo (before)   = [%s]",p3);

mymemmove(p3, p4, size);

printf("\n\nFrom (after) = [%s]",p4);
printf("\nTo (after)   = [%s]",p3);

printf("\n--------------------------------\n");

/* ----------------------------------------
*
* CASE 3 : No overlap
*
* --------------------------------------- */

p1 = (char *) malloc(30);
memset(p1,30,'\0');
size=10;

strcpy(p1,"ABCDEFGHI");

p2 = p1 + 15;

printf("\n--------------------------------\n");
printf("\nFrom (before) = [%s]",p1);
printf("\nTo (before)   = [%s]",p2);

mymemmove(p2,p1,size);

printf("\n\nFrom (after) = [%s]",p1);
printf("\nTo (after)   = [%s]",p2);

printf("\n--------------------------------\n");

printf("\n\n");

return 0;
}


void *mymemmove(void *to, const void *from, size_t size)
{
unsigned char *p1;
const unsigned char *p2;

p1 = (unsigned char *) to;
p2 = (const unsigned char *) from;

p2 = p2 + size;

// Check if there is an overlap or not.
while (p2 != from && --p2 != to);

if (p2 != from)
{
// Overlap detected!

p2  = (const unsigned char *) from;
p2  = p2 + size;
p1  = p1 + size;

while (size-- != 0)
{
*--p1 = *--p2;
}
}
else
{
// No overlap OR they overlap as CASE 2 above.
// memcopy() would have done this directly.

while (size-- != 0)
{
*p1++ = *p2++;
}
}
return(to);
}

And here is the output

--------------------------------

From (before) = [ABCDEFGHI]
To   (before) = [CDEFGHI]

From (after) = [ABABCDEFGHI]
To   (after) = [ABCDEFGHI]

--------------------------------

From (before) = [ABCDEFGHI]
To   (before) = [α╙ABCDEFGHI]

From (after) = [CDEFGHI]
To   (after) = [ABCDEFGHI]

--------------------------------

From (before) = [ABCDEFGHI]
To   (before) = [FEδ‼&:F]

From (after) = [ABCDEFGHI]
To (after)   = [ABCDEFGHI]

--------------------------------
So then, whats the difference between the implementation of memmove() and memcpy(). Its just that memcpy() will not care if the memories overlap and will either copy from left to right or right to left without checking which method to used depending on the type of the overlap. Also note that the C code proves that the results are the same irrespective of the Endian-ness of the machine.

Posted in C - Fresher questions0 Comments

c training – atoi function implementation

Write your own C program to implement the atoi() function.

The prototype of the atoi() function is …

int atoi(const char *string);

Here is a C program which explains a different way of coding the atoi() function in the C language.

#include<stdio.h>

int myatoi(const char *string);

int main(int argc, char* argv[])
{
printf("\n%d\n", myatoi("1998"));
getch();
return(0);
}

int myatoi(const char *string)
{
int i;
i=0;
while(*string)
{
i=(i<<3) + (i<<1) + (*string - '0');
string++;

// Dont increment i!

}
return(i);
}

Try working it out with a small string like “1998″, you will find out it does work!.

Ofcourse, there is also the trivial method ….

"1998" == 8 + (10 * 9) + (100 * 9) + (1 * 1000) = 1998

This can be done either by going from right to left or left to right in the string

One solution is given below

int myatoi(const char* string)
{
int value = 0;

if (string)
{
while (*string && (*string <= '9' && *string >= '0'))
{
value = (value * 10) + (*string - '0');
string++;
}
}
return value;
}

Note that these functions have no error handling incorporated in them (what happens if someone passes non-numeric data (say “1A998″), or negative numeric strings (say “-1998″)). I leave it up to you to add these cases. The essense is to understand the core logic first.

Posted in C - Fresher questions1 Comment

c training – linked list

How can I search for data in a linked list?

The only way to search a linked list is with a linear search, because the only way a linked list’s members can be accessed is sequentially. Sometimes it is quicker to take the data from a linked list and store it in a different data structure so that searches can be more efficient.


Posted in Data Structures0 Comments