Reputation: 1589
I've looked all over for an answer to this but can't seem to find one. (I have fairly limited experience with C++)
In my library, I free a string. (Amazing, huh?)
This is where the problem arises. I have a struct which contains a char* that may be allocated on the heap or may not be. While it is a valid pointer it cannot be freed.
IE
char* s1 = "A String";
char* s2 = (char*)memcpy(malloc(9), s1, 9);
free(s2);
free(s1);
Will cause an error on "free(s1);" (As it should) Because s1 does not actually need to be freed, (It isn't on the heap) how can I handle this in an "acceptable" way? (On similar topics the answer of "let it crash" didn't seem reasonable IMO)
Because the struct is not solely created by the library, it is not possible to guarantee that a string will be properly copied over using something like memcpy.
Seeing as this is a windows library, I don't need to worry about using ISO C stuff or standard C functions.
Upvotes: 5
Views: 1490
Reputation: 547
For things involving memory allocation in C++, smart pointers are awesome. Just sayin'.
http://www.cplusplus.com/reference/std/memory/auto_ptr/
http://www.boost.org/doc/libs/1_45_0/libs/smart_ptr/smart_ptr.htm
Upvotes: 0
Reputation: 283684
Seeing as this is a Windows library, make the argument a BSTR
. Then you require the user to allocate it properly (with SysAllocString
) and you're guaranteed to use a matching deallocator.
Other methods are just... bad. If your user has a different compiler, then you can't free()
the string even if they did use malloc
.
[Note: Converted from a comment at James's request, this really is just a Windows-specific case of the last of his suggestions]
Further note: BSTR is Unicode. I kinda sorta remember seeing a way to use the BSTR allocator to store ANSI strings, seems that SysAllocStringByteLen
does that, but be warned that putting ANSI data in a BSTR will be highly counterintuitive to anyone familiar with BSTR.
Upvotes: 2
Reputation: 7083
I have done something similar in the past, where I would use a stack-allocated string in some cases, and a heap-allocated string in others, but they ultimately get passed off to some other common code.
What I have done in that case, is to have two pointers. One is either NULL, or a heap-allocated string. The other pointer points to either the stack-allocated or the same heap-allocated memory as the former. When you go to do your free(), you check the former pointer only.
Of course, that's going to look nasty in an exposed API. In my case it was internal code only.
Upvotes: 0
Reputation: 67223
Store all strings in the heap, then you'll know they all need to be freed. If the string exists as in global memory, copy it to a heap buffer.
Upvotes: 0
Reputation: 58677
This is the sort of thing that's known at compile time. You look at the code and know what to free and what not to. So don't think of a way to defer it to runtime, because apart from the fact you won't find a way in this case, it's the wrong way of doing things in C++. When you can do it statically, do it statically.
Use the type system. Use RAII.
Upvotes: 0
Reputation: 1695
You can malloc char *s1
and place "A String"
as value. After that, you can free s1
.
Upvotes: 0
Reputation: 355079
In C++, you shouldn't be worrying about this at all. Use std::string
and have it manage memory for you, automatically. Don't manage memory manually.
If you were to do this manually, you would need to manage the resource yourself, by
Upvotes: 6