This is from a Codewars challenge so I'll leave out unnecessary code from this function. Basically if n <= 1
, I need to return an empty string.
char* sc(int n)
{
if(n > 1) {
//irrelevant code
}
//return strdup("");
return "";
}
If the value being passed is -1
, when I use return "";
I get a "Test crashed" message but when I use return strdup("");
I pass the test. Just wondering why this is?
Edit: This is how the function is called. It is only the last test that fails.
#include <criterion/criterion.h>
#include <string.h>
char* sc(int);
void dotest(int n, const char* expect)
{
char* actual = sc(n);
cr_expect(!strcmp(actual, expect), "Expected: '%s', got: '%s'\n", expect, actual);
free(actual);
}
Test(the_multiply_function, should_pass_all_the_tests_provided) {
dotest(2,"Aa~ Pa! Aa!");
dotest(6, "Aa~ Aa~ Aa~ Aa~ Aa~ Pa! Aa!");
dotest(7, "Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Pa!");
dotest(10, "Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Aa~ Pa!");
dotest(1, "");
dotest(-1, "");
}
For usage of free()
, from C11
, chapter §7.22.3.3 (emphasis mine)
The
free
function causes the space pointed to byptr
to be deallocated, that is, made available for further allocation. Ifptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by a memory management function, or if the space has been deallocated by a call tofree
orrealloc
, the behavior is undefined.
and, for strdup()
(again emphasis mine)
The
strdup()
function returns a pointer to a new string which is a duplicate of the strings
. Memory for the new string is obtained withmalloc()
, and can be freed withfree()
.
So, when you use return strdup("");
, the pointer which is returned is eligible to be passed to free()
- everything is alright.
OTOH, by saying return "";
, you're returning a pointer to the first element of a string literal which is not a suitable candidate to be passed to free()
, as mentioned above, it invokes undefined behaviour.
The crash or segmentation fault is one of the many side effects of UB.