Task:
Allocate (with malloc(3)) and return a substring from the string
s
. The substring begins at indexstart
and is of maximum sizelen
.Return value: The substring.
NULL
if the allocation fails.
Hello, after a few hours I decided to ask for some clarifications. I have the following functions and some error from Valgrind I can't understand, that shows up even if everything is correct. (ft_strlen(s)
I call from my own library, where also lib for malloc is put).
char *ft_substr(char const *s, unsigned int start, size_t len)
{
unsigned int x;
char *a;
unsigned int i;
i = 0;
if (s == NULL)
return (0);
if (start > ft_strlen(s))
{
if (!(a = (char *)malloc(0*sizeof(char))))
return (0);
return (a);
}
if ((start + len) < ft_strlen(s))
x = len;
else
x = ft_strlen(s) - start;
if (!(a = (char *)malloc((x + 1) * sizeof(char))))
return(0);
while (i < x)
{
a[i] = s[start + i];
i++;
}
a[i] = '\0';
return (a);
}
I left there one error on purpose. If I am suppose to return null if allocation fails, why below instead of 0
should be 1
? Anyway it does not change the errors presented below.
if (!(a = (char *)malloc(0 * sizeof(char))))
ERRORS:
==4817== Invalid read of size 1
==4817== at 0x483FED4: strcmp (in /usr/lib/x86_64-linux-gnu/valgrind vgpreload_memcheck-amd64-linux.so)
==4817== by 0x4039BC: main (ft_substr_test.cpp:28)
==4817== Address 0x4dad0d0 is 0 bytes after a block of size 0 alloc'd
==4817== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==4817== by 0x403B58: ft_substr (in /home/tony/42cursus/0lvl_libft_1week/libftTester/a.out)
==4817== by 0x4039A4: main (ft_substr_test.cpp:27)
==4817==
Your function has multiple problems:
start
, x
and i
should be size_t
.malloc(0)
has implementation defined behavior. You should allocate at least 1 byte for the null terminator and set it before returning the pointer to the empty string or return NULL
if the specification says you should.ft_strlen()
just once.start > ft_strlen(s)
can be handled in the general case if an empty string should be returned.Here is a modified version:
char *ft_substr(char const *s, size_t start, size_t len) {
size_t i, slen;
char *a;
if (s == NULL) {
return NULL;
}
slen = ft_strlen(s);
if (start > slen) {
start = slen;
}
if (len > slen - start) {
len = slen - start;
}
if (!(a = malloc((len + 1) * sizeof(char)))) {
return NULL;
}
for (i = 0; i < len; i++) {
a[i] = s[start + i];
}
a[i] = '\0';
return a;
}
PS: you may need to reformat the code to fit the local 42 norminette...