Reputation: 168
I'm trying to make an algorithm for strncpy
I read how it work in the manual and made my algorithm
then I made a test to see if there's any difference between my ft_strncpy
and the real strncpy
#include <string.h>
#include <stdio.h>
char *ft_strncpy(char *dest, char *src, unsigned int n)
{
unsigned int i;
i = 0;
while (i < n && src[i] != '\0')
{
dest[i] = src[i];
i++;
}
while (i < n)
{
dest[i] = '\0';
i++;
}
return (dest);
}
int main(void)
{
char src1[] = "123456789q00000";
char dest1[] = "zzz";
printf("my output\n");
printf("src1: %s\n", src1);
ft_strncpy(dest1, src1, 8);
printf("dest1: %s\n", dest1);
printf("\nhow it should be\n");
char src2[] = "123456789q00000";
char dest2[] = "zzz";
printf("src2: %s\n", src2);
strncpy(dest2, src2, 8);
printf("dest2: %s\n", dest2);
}
the how it should be
section supposed to be the right output of the real strncpy
but I'm having weird outputs just like in the code I provided
I get this error
*** buffer overflow detected ***: terminated
signal: aborted (core dumped)
what I understood from the manual is
strncpy
copies n
first characters from *src
to *dest
so a code like
char src2[] = "123456789q00000";
char dest2[] = "zzz";
printf("src2: %s\n", src2);
strncpy(dest2, src2, 10);
printf("dest2: %s\n", dest2);
should output : 123456789q
as the value of dest
I'm I missing smth here?
Upvotes: 2
Views: 197
Reputation: 144550
strncpy(dest2, src2, 10);
has undefined behavior because it will modify 10 bytes starting with dest2[0]
, yet dest2
is only 4 bytes long.
You have the same problem in ft_strncpy(dest1, src1, 8);
for the same reason.
Nothing can be concluded from tests with code that has undefined behavior. The code must be corrected first.
You code for ft_strncpy()
seems correct, except for the type unsigned int
for the length argument which should be size_t
. Using unsigned int
is probably a requirement for your school project, but a debatable one, among other counter-productive requirements such as banning for
loops and mandating parentheses around the return
value.
Here is a modified version:
#include <string.h>
#include <stdio.h>
char *ft_strncpy(char *dest, char *src, unsigned int n)
{
unsigned int i;
i = 0;
while (i < n && src[i] != '\0')
{
dest[i] = src[i];
i++;
}
while (i < n)
{
dest[i] = '\0';
i++;
}
return (dest);
}
void dump(const char *prefix, const char *p, size_t size)
{
size_t i;
printf("%s: %s [", prefix, p);
i = 0;
while (i < size) {
printf(" %.2X", (unsigned char)p[i]);
i++;
}
printf(" ]\n");
}
int main(void)
{
char src1[] = "zzz";
char dest1[] = "123456789q00000";
printf("my output\n");
printf("src1: %s\n", src1);
ft_strncpy(dest1, src1, 8);
dump("dest1: ", dest1, sizeof dest1);
printf("\nhow it should be\n");
char src2[] = "zzz";
char dest2[] = "123456789q00000";
printf("src2: %s\n", src2);
strncpy(dest2, src2, 8);
dump("dest1: ", dest1, sizeof dest1);
return 0;
}
Output:
my output
src1: zzz
dest1: : zzz [ 7A 7A 7A 00 00 00 00 00 39 71 30 30 30 30 30 00 ]
how it should be
src2: zzz
dest1: : zzz [ 7A 7A 7A 00 00 00 00 00 39 71 30 30 30 30 30 00 ]
Upvotes: 0
Reputation: 168
Arrays in c are not dynamic so
I can't just initialize it with a string then try changing it to a bigger one
that will lead to an undefined behavior
besides there's a corner-case where it might not add the terminating null character so I won't be able to print it with printf
because it's not a string anymore, it's an array.
conclusion: Be more cautious when modifying strings.
(answer by the help of @Someprogrammerdude and @n. 1.8e9-where's-my share m.)
Upvotes: 2