char *ft_substr(char const *s, unsigned int start, size_t len)
{
size_t i;
size_t d;
char *subs;
i = 0;
d = 0;
subs = (char *)malloc(sizeof(char) * (len 1));
if (!subs || !s)
{
return NULL;
}
while (s[i])
{
if (i >= start && d < len)
{
subs[d] = s[i];
d ;
}
i ;
}
subs[d] = '\0';
return subs;
}
The code that appears above is the substr function I wrote, when I checked the memory leak using Memd, I noticed that there was an error on the 14th line.
subs = (char *)malloc(sizeof(char) * (len 1));
Unfortunately, I do not have the authority to install Valgrind on the device I use, so I was able to test with memd. I'm fairly new to C, can you explain why I'm getting a memory leak error and how can I fix it?
CodePudding user response:
The key to solving this would be to add a guard to the beginning of your function, before you allocate for subs which may never be returned and thus be unable to be freed.
if (!s) return NULL;
You can still check later when subs is allocated and return NULL if that allocation fails.
CodePudding user response:
subs = (char *)malloc(sizeof(char) * (len 1));
if (!subs || !s)
{
return (NULL);
}
I the sub-statement of the if statement will get the control when s is equal to NULL when there will be a memory leak.
Pay attention to that you may remove the check whether s is a null pointer as all C standard string functions do. If the user will call the function passing a null pointer then there will be undefined behavior.
And the call of malloc can allocate more memory then it is required.
Also the types of the second and third parameters are inconsistent.
char *ft_substr(char const *s, unsigned int start, size_t len)
The both should have the type size_t.
CodePudding user response:
If you want to make it safe you need not only to check if s is not NULL but also if the start is not past the length of the string.
Try to have only one return point from the function and rather use positive checks (ie if something is valid, instead of checking if it is invalid).
char *ft_substr(char const * restrict s, const size_t start, const size_t length)
{
char *subs = NULL;
if(s)
{
size_t len = strlen(s);
if(len >= start)
{
subs = malloc(length 1);
if(subs)
{
char *wrk = subs;
size_t tocopy = length;
s = start;
while(tocopy-- && (*wrk = *s ));
*wrk = 0;
}
}
}
return subs;
}
