Why does this strncpy() implementation crashes on second run, while the first run works ok?
strncpy
Copy characters from string Copies the first
ncharacters of source
to destination. If the end of the source C string (which is signaled
by a null-character) is found beforencharacters have been copied,
destination is padded with zeros until a total ofncharacters have
been written to it.No null-character is implicitly appended at the end of destination if
source is longer thann(thus, in this case, destination may not be
a null terminated C string).
char *strncpy(char *src, char *destStr, int n)
{
char *save = destStr; //backing up the pointer to the first destStr char
char *strToCopy = src; //keeps [src] unmodified
while (n > 0)
{
//if [n] > [strToCopy] length (reaches [strToCopy] end),
//adds n null-teminations to [destStr]
if (strToCopy = '\0')
for (; n > 0 ; ++destStr)
*destStr = '\0';
*destStr = *strToCopy;
strToCopy++;
destStr++;
n--;
//stops copying when reaches [dest] end (overflow protection)
if (*destStr == '\0')
n = 0; //exits loop
}
return save;
}
/////////////////////////////////////////////
int main()
{
char st1[] = "ABC";
char *st2;
char *st3 = "ZZZZZ";
st2 = (char *)malloc(5 * sizeof(char));
printf("Should be: ZZZZZ\n");
st3 = strncpy(st1, st3, 0);
printf("%s\n", st3);
printf("Should be: ABZZZZZ\n");
st3 = strncpy(st1, st3, 2);
printf("%s\n", st3);
printf("Should be: ABCZZZZZ\n");
st3 = strncpy(st1, st3, 3);
printf("%s\n", st3);
printf("Should be: ABC\n");
st3 = strncpy(st1, st3, 4);
printf("%s\n", st3);
printf("Should be: AB\n");
st2 = strncpy(st1, st2, 2);
printf("%s\n", st2);
printf("Should be: AB\n");
st2 = strncpy(st1, st2, 4);
printf("%s\n", st2);
}
You get a segmentation fault because
the destination is a string literal. String literals must not be modified, and often they are stored in write-protected memory. So when you call
with an
n > 0, you are trying to modify the string literal and that results in a crash (not necessarily, but usually).In the copy loop, you have forgotten to dereference
strToCopyand wrote
=instead of==, sostrToCopyis set toNULL, causing further dereferences ofstrToCopyto invoke undefined behaviour.