SPB
SPB

Reputation: 4218

having memcpy problem

char *a=NULL;

char *s=NULL; 

a=(char *)calloc(1,(sizeof(char))); 

s=(char *)calloc(1,(sizeof(char))); 

a="DATA"; 

memcpy(s,a,(strlen(a))); 

printf("%s",s);

Can you plz tell me why its printing DATA½½½½½½½½■ε■????How to print only DATA?? Thanks

Upvotes: 3

Views: 2745

Answers (6)

ShinTakezou
ShinTakezou

Reputation: 9681

Your

a="DATA";

trashes the pointer to the allocated memory. It does not copy "DATA" into the memory. Which however would be not enough to store it, since

a=(char *)calloc(1,(sizeof(char))); 

allocates a single char. While

memcpy(s,a,(strlen(a)));

copies what is pointed now by a (string literal "DATA") to the memory which is pointed by s. But again, s points to a single char allocated, and copying more than 1 char will overwrite something and results in a bug.

strlen(a) gives you 4 (the length of "DATA") and memcpy copies exactly 4 char. But to know where a string ends, C uses the convention to put a final "null" char ('\0') to its end. So indeed "DATA" is, in memory, 'D' 'A' 'T' 'A' '\0'.

All string related function expect the null byte, and they don't stop printing until they find it.

To copy strings, use instead strcpy (or strncpy), it copies the string with its final null byte too. (strcpy is less "secure" since you can overflow the destination buffer).

But the biggest problem I can see here is that you reserve a single char only for a (and you trash it then) and s, so DATA\0 won't fit anywhere.

Upvotes: 2

unwind
unwind

Reputation: 400109

You are first allocating memory, then throwing that memory away by re-assigning the pointer using a string literal. Your arguments to calloc() also look very wrong.

Also, memcpy() is not a string copying function, it doesn't include the terminator. You should use strcpy().

The best way to print only DATA would seem to be

puts("DATA");

You need to be more clear on what you want to do, to get help with the pointers/allocations/copying.

Upvotes: 2

Till
Till

Reputation: 994

strlen does only count the chars without the terminator '\0'. Without this terminator printf does not know the end od the string.

Solution: memcpy(s,a,(strlen(a)+1));

Upvotes: 2

Carl Smotricz
Carl Smotricz

Reputation: 67820

You need to store a terminating \0 after that DATA string so printf() will know to stop printing.

You could replace memcpy with strcat:

strcat(s, a);

should do it.

Note, however, that there's a bug earlier on:

calloc(1,sizeof(char)) 

will only allocate a single byte! That's certainly not enough! Depending on the implementation, your program may or may not crash.

Upvotes: 1

Wolph
Wolph

Reputation: 80111

You are reserving space for 1 character so you are actually using the memory of some other variable when you are writing "DATA" (which is 4 characters + the trailing \0 to mark the end of the string).

a=(char *)calloc(1,(sizeof(char)));

For this example you would need 5 characters or more:

a=(char *)calloc(5, (sizeof(char)));

Upvotes: 1

Pete Kirkham
Pete Kirkham

Reputation: 49331

Strings in C are terminated by a zero character value (nul).

strlen returns the number of characters before the zero.

So you are not copying the zero.

printf keeps going, printing whatever is in the memory after s until it hits a zero.

You also are only creating a buffer of size 1, so you are writing data over whatever is after s, and you leak the memory calloc'd to a before you set a to be a literal.

Allocate the memory for s after finding the length of the string, allocating one more byte to include the nul terminator, then copy a into s. You don't need to allocate anything for a as the C runtime looks after storing the literal "DATA".

Upvotes: 6

Related Questions