I have a use case where I can get pointers of strings allocated either in memory or literals. Now the latter can't be freed so that's a problem if I pass the wrong one. Is there a way to know which one is allocated and which not?
char *b = "dont free me!";
if(!IS_LITERAL(b)) {
free(b);
}
I imagine something like that.
My example:
Scenario 1: literal
char *b = "dont free me!";
scruct elem* my_element = mylib_create_element(b);
// do smth
int result = mylib_destroy_element(my_element); // free literal, very bad
Scenario 2: in heap
char *b = malloc(sizeof(char)*17); // example
strncpy(b, "you can free me!",17);
scruct elem* my_element = mylib_create_element(b);
// do smth
int result = mylib_destroy_element(my_element); // free heap, nice
How the user calls mylib_create_element(b);
is not under my control. If he frees before mylib_destroy_element
it can crash. So it has got to be mylib_destroy_element
that cleans up.
You can only ask user to explicitly mark their input as literal or allocated string.
However, as @Mints97 mentions in his answer, basically this approach is architecturally incorrect: you force user of your library for some explicit actions, and if he forgets to, it leads most likely to a memory leak (or even to an application crash). So use it only if:
Implementation example
Testing performance (note #1)
I benchmarked my libtsjson library with following code (800k iterations):
My CPU is Intel Core i7 860. If
NODE_NAME
is just a macro, time per iteration was 479ns IfNODE_NAME
is a memory allocation, time per iteration was 609nsHinting user or compiler (note #2)
Add a hint to all such pointers, i.e. Linux static source analyser Sparse may catch such issues
(not completely sure about outputs of Sparse)
Use simple
typedef
to make compiler raise a warning when you do something wrong:This approach is one more step to a world of a dirty C hacks, i.e.
sizeof(*aas_t)
is now > 1.Full source with changes may be found here. If compiled with
-DAAS_STRICT
it will raise tons of errors: https://ideone.com/xxmSat Even for correct code it can complain aboutstrcpy()
(not reproduced on ideone).The simple answer is you cannot do this since C language does not demarcate stack, heap and data section.
If you wanted to have a guess - you could collect address of the first variable on the stack, address of the calling function and address of a byte of memory allocated to heap; and then compare it with your pointer - a very bad practice with no guarantees.
It's best for you to revamp your code such a way that you don't come across this issue.