Destructor on const char * - c++

In my program, i have line like this:
const char * str = getStr();
Do i need to call destructor on str [] at the end of function to prevent memory leaks?

Question does not contain enough information to tell, it depends what getStr() does. For example:
const char *getStr() {
return "boo";
}
then you must not call delete.
const char *getStr() {
return new char;
}
then you should call delete str; to avoid a memory leak (and must not call delete[]).
const char *getStr() {
return new char[10];
}
then you should call delete[] str; to avoid a memory leak (and must not call delete).
const char *getStr() {
return 0;
}
then it doesn't matter what you do, calling any kind of delete on str has no effect.
Ownership of resources, and how to release any resources owned, are part of the interface to a function, and should be documented at the same time as you document what the return value actually is.

It all depends on what getStr() does. It may even be that you have to call free on the pointer if getStr() created it with malloc. It may be that getStr() is returning a pointer to a static area (not very thread safe, but it happens) or any number of other things.
Part of the contract and documentation for getStr() should be who owns the pointer it returns.
Here are some examples of possible getStr() functions...
In this case getStr() owns the pointer and you don't have to do anything to free it. OTOH, what's being pointed at may change the next time you call getStr() so you should probably make your own copy if you need to keep it around for any length of time:
const char *getStr()
{
static char buf[30] = "Silly counter";
buf[0] = buf[0] + 1;
return buf;
}
In this case, you will eventually need to call free on the pointer returned:
const char *getStr()
{
return strdup("Silly string");
}
In this case, you will need to call plain old delete on the pointer returned:
const char *getStr()
{
return new char;
}
In this case, you will need to call delete [] on the pointer returned:
const char *getStr()
{
return new char[50];
}
There are many other possibilities. As I stated previously, part of the contract for a function (which should appear in its documentation) is who owns the pointer returned and how that data pointed to must be disposed of if doing so is the caller's responsibility.

It depends on how getStr() has been designed. It could return a pointer to a string that is still owned by someone else (and in this case the answer is no) or it may return a pointer to and the caller becomes the owner (and in this case the answer is yes).
You should check the documentation of getStr to know.
If the ownership of the returned area is of the caller then probably in C++ returning an std::string would have been a much better idea.

It's a good idea to do so if it's going out of scope. I'd recommend also setting the pointer to null to ensure it isn't dangling:
delete[] str;
str = null;

Related

Chances of memory leak in cJSON_Print in CPP [duplicate]

I am using the cJSON library and I have a function as follows:
void printJsonObject(cJSON *item)
{
char *json_string = cJSON_Print(item);
printf("%s\n", json_string);
}
Will this function leak memory?
I've never used cJSON , but as per the function definition present in this link, it looks like
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
and
static char *print_value(cJSON *item,int depth,int fmt);
From print_value() function, the pointer returned is allocated by cJSON_strdup() [which is a modified version of the combination of malloc() and memcpy()] and it is returned to the caller.
As I see no method to track the allocation, IMO, the allocated memory needs to be free()d by the caller function. Otherwise, it will be a memory leak.
Yes, it is a memory leak.
Buffers returned by cJSON_Print must be freed by the caller. Please use the proper API (cJSON_free) rather than directly calling stdlib free.
See the cJSON maintainer's comment: https://github.com/DaveGamble/cJSON/issues/5#issuecomment-298469697
I recommend:
void printJsonObject(cJSON *item)
{
char *json_string = cJSON_Print(item);
if (json_string)
{
printf("%s\n", json_string);
cJSON_free(json_string);
}
}

using "new" and "delete" inside class function

I want to be sure that using new and delete to free heap memory is done as needed.
Following function returns a char *. Inside each function I use new for the returned value, and I delete afterwards.
Is it the right way to free heap memory for function return?
const char *myIOT2::_devName()
{
char *ret = new char[MaxTopicLength2];
if (strcmp(addGroupTopic, "") != 0)
{
snprintf(ret, MaxTopicLength2, "%s/%s/%s", prefixTopic, addGroupTopic, deviceTopic);
}
else
{
snprintf(ret, MaxTopicLength2, "%s/%s", prefixTopic, deviceTopic);
}
return ret;
}
const char *myIOT2::_availName()
{
char *ret = new char[MaxTopicLength2];
const char *DEV = _devName();
snprintf(ret, MaxTopicLength2, "%s/Avail", DEV);
delete DEV;
return ret;
}
To point out: the fact the I DEV: const char *DEV = _devName(); in order to use it as a parameter in snprintf(ret, MaxTopicLength2, "%s/Avail", DEV); just to be able to delete it later as delete DEV; - is this correct?
At least as I see things, you really only have two sane choices here. One is for the caller to handle all the memory management. The other is for the callee to handle all the memory management.
But what you're doing right now (callee handles allocation, caller handles de-allocation) is a path to madness and memory leaks.
If the caller is going to manage the memory, this all becomes fairly simple:
const char *myIOT2::_devName(char *ret, size_t maxlen)
{
if (strcmp(addGroupTopic, "") != 0)
{
snprintf(ret, maxlen, "%s/%s/%s", prefixTopic, addGroupTopic, deviceTopic);
}
else
{
snprintf(ret, maxlen, "%s/%s", prefixTopic, deviceTopic);
}
return ret;
}
If the callee is going to handle all the memory management, you'd normally use std::string. Since you're on an Arduino, however, std::string isn't available, and you need to use their own String class instead. Either way, you simply allocate a String object and put your contents into it. It takes care of the actual memory allocation to hold the contents, and will free its contents when the String object is destroyed.
Given the small amount of memory normally available on an Arduino, having the caller allocate the memory is usually going to work out better. But (especially if this is something that doesn't happen very often, so you won't run into heap fragmentation problems) allocating space on the heap can work reasonably well also.
But I'll repeat: trying to mix memory management so the callee allocates and the caller deletes...is the stuff of nightmares. When you read about C++ circa 1993, and hear about lots of problems with memory leaks...this is exactly the sort of thing that led to them.
ret allocated memory:
const char *myIOT2::_devName()
{
char *ret = new char[MaxTopicLength2];
return ret;
}
And below, you'll see that by deleting DEV, you will free the memory, because it's actually ret. But this time, you should remove ret2 somewhere else since it's the return value and there's no way to delete it inside that scope:
const char *myIOT2::_availName()
{
char *ret2 = new char[MaxTopicLength2];
const char *DEV = _devName();
delete[] DEV;
return ret2;
}
Also, note the following:
char* str = new char [30]; // Give str a memory address.
// delete [] str; // Remove the first comment marking in this line to correct.
str = new char [60]; /* Give str another memory address with
the first one gone forever.*/
delete [] str; // This deletes the 60 bytes, not just the first 30.

copy char* to another char** using dynamic allocation

I am still new in this topic but can someone explain me how can I copy one char* to another char** as parameter without getting memory leaks?
void Hardware::copyString(char** dest, const char* source)
{
size_t length = strlen(source);
auto string = new char[length+1];
strncpy(string, source, length);
string[length] = '\0';
*dest = string;
//need to be freed
free(string); //if i free here the data would getting lost
}
and a ctor:
Hardware::Hardware(const char* name, int cost)
{
copyString(&name_, name);
cost_ = cost;
}
main.cpp
Hardware hard("CPU", 250)
Where should I free this without getting memory leaks and have the right output?
Regardless of the issues in your implementation, the simple answer to your question would be to free it at the destructor.
If you don't want to expose the name_ variable, you can free it inside the destructor of the Hardware class.
Hardware::~Hardware()
{
delete[] name_;
}
If you free is inside the function itself, you're deleting the heap allocation, even though you're passing different variables, because they're pointing to the same memory location.
But, as others suggested, the best way to work with strings is to use std::string.

How to efficiently move underlying data from std::string to a variable of another type?

EDIT: Sorry everyone, I don't think this toy example really reflected my problem. What I should have asked is if there is a way to release a std::string object's buffer. There is not, and that makes sense. Thanks!
Suppose I have the following (broken) code:
void get_some_data(MyCustomContainer& val)
{
std::string mystr = some_function();
val.m_data = &mystr[0];
}
This won't work, because the memory pointed by mystr is freed at the end of get_some_data, and the memory referenced by val.m_data will be invalid.
How can I tell a std::string "Don't free your memory buffer at your destructor!" ? I don't want to copy the data. The MyCustomerContainer object will handle the memory free-ing at its destructor.
You cannot do this without breaking the rules. The std::string class is not allowed to release its ownership explicitly. In fact, a std::string might not even have any memory allocated due to SBO optimization:
std::string str1 = "not allocating";
std::string str2 = "allocating on the heap, the string is too large";
This behavior is completely platform- and implementation-dependent. If a string doesn't allocate its buffer on the heap, the data is placed on the stack, which doesn't need de-allocation.
{
std::string str1 = "not allocating";
} // no buffer freed
So even if there were a way to tell the string not to de-allocate its buffer, there is no way to tell if the buffer is managed on the heap or not.
Even if there were a way to tell if the string uses the stack, you'd have to allocate a buffer in place as a class member and copy its content.
The idea of transferring a string's data and stealing its ownership over that string's memory resource is fundamentally broken as you can't get away without copying, simply because there might be no ownership to steal.
What I recommend is for you to copy the string content in all cases if you don't want to change how MyCustomContainer works:
void get_some_data(MyCustomContainer& val)
{
std::string mystr = some_function();
val.m_data = new char[mystr.size()];
std::memcpy(val.m_data, mystr.data(), mystr.size());
}
In contrast, if you allow MyCustomContainer to store a std::string, you could actually get away without copying when a buffer is allocated by moving the string:
void get_some_data(MyCustomContainer& val)
{
// let m_data be a std::string
val.m_data = some_function();
// The above is equivalent to this:
// std::string mystr = some_function();
// val.m_data = std::move(mystr);
}
Moving a string will invoke move assignation. With move assignation, the string implementation will transfer the ownership of the mystr's buffer into m_data. This will prevent any additional allocation.
If mystr didn't allocate, then the move assignment will simply copy the data (so no allocation there, either).
The right way to fix this problem is:
class MyCustomContainer {
public:
std::string m_data;
};
void get_some_data(MyCustomContainer& val) {
val.m_data = some_function();
}
The get_some_data could even be made into a member function, which would make the usage even easier at the callsite, and perhaps allow m_data to be private instead of exposed.
If .m_data is an std::string you can take advantage of std::string's move-assignment operator:
val.m_data = std::move(mystr);
If m_data is not an std::string you are pretty much out of luck, the internal buffer is inaccessible (as it should be).
No, you cannot. std containers will only give up their managed memory (and then only sometimes) to std containers of the same type.
For string this would be impossible regardless, as most implementations do a short string optimization and store short strings internally.
You could throw the std string into a global buffer somewhere and reap it at cleanup, but that gets insanely complex.
If you want you can use this code that causes Undefined Behavior, so it should not be used, but if you are working on some toy project of your own that will be quickly abandoned you can see if it works for you.
// REQUIRES: str is long enough so that it is using heap,
// std::string implementation does not use CoW implementation...
// ...
char* steal_memory(string&& str){
alignas(string) char buff[sizeof(string)];
char* stolen_memory = const_cast<char*>(str.data());
new(buff) string(move(str));
return stolen_memory;
}
If you want to handle short string you should add malloc and copy from buffer for that case.
Main idea here is to use placement new that takes the ownership from our input string, and not calling the destructor on string in buff. No destructor means no calls to free, so we can steal memory from the string.
Unfortunately const_cast is UB in this case so like I said you should never use this code in serious code.
You can do mystr static
void get_some_data(MyCustomContainer& val)
{
static std::string mystr;
mystr = some_function();
val.m_data = &mystr[0];
}
but, in this way, you have only one mystr for all get_some_data() calls; so
get_some_data(mcc1);
get_some_data(mcc2);
// now both `mcc1.m_data` and `mcc2.m_data` point to the same value,
// obtained from the second `some_function()` call
If you can compile-time enumerate the calls to get_some_data(), you can differentiate your mystr using a template index
template <std::size_t>
void get_some_data(MyCustomContainer& val)
{
static std::string mystr;
mystr = some_function();
val.m_data = &mystr[0];
}
get_some_data<0U>(mcc1);
get_some_data<1U>(mcc2);
// now `mcc1.m_data` and `mcc2.m_data` point to different values

How to return local array in C++?

char *recvmsg(){
char buffer[1024];
return buffer;
}
int main(){
char *reply = recvmsg();
.....
}
I get a warning:
warning C4172: returning address of local variable or temporary
I would suggest std::vector<char>:
std::vector<char> recvmsg()
{
std::vector<char> buffer(1024);
//..
return buffer;
}
int main()
{
std::vector<char> reply = recvmsg();
}
And then if you ever need char* in your code, then you can use &reply[0] anytime you want. For example,
void f(const char* data, size_t size) {}
f(&reply[0], reply.size());
And you're done. That means, if you're using C API, then you can still use std::vector, as you can pass &reply[0] to the C API (as shown above), and reply to C++ API.
The bottomline is : avoid using new as much as possible. If you use new, then you've to manage it yourself, and you've to delete when you don't need it.
You need to dynamically allocate your char array:
char *recvmsg(){
char* buffer = new char[1024];
return buffer;
}
for C++ and
char *recvmsg(){
char* buffer = malloc(1024);
return buffer;
}
for C.
What happens is, without dynamic allocation, your variable will reside on the function's stack and will therefore be destroyed on exit. That's why you get the warning. Allocating it on the heap prevents this, but you will have to be careful and free the memory once done with it via delete[].
The warning message is correct. You're returning the address of a local array which disappears after the function returns.
You can do this using dynamic memory allocation:
char *recvmsg(){
char *buffer = (char*)malloc(1024);
return buffer;
}
The catch is that you need to make sure you free() the pointer later on to avoid a memory leak.
Alternatively, you can pass the buffer into the function.
void recvmsg(char *buffer,int buffer_size){
// write to buffer
}
void main(){
char buffer[1024];
recvmsg(buffer,1024);
}
This avoids the need for a memory allocation. This is actually the preferred way to do it.
The problem is that buffer lives on the stack and goes out of scope the moment you exit recvmsg.
You could allocate buffer on the heap:
char *recvmsg(){
char *buffer = malloc(1024);
return buffer;
}
Note that now the caller is responsibe for disposing of the allocated memory:
void main(){
char *reply = recvmsg();
free(reply);
}
You have a few options...The way you're doing it now is going to cause undefined behavior as the array will go out of scope once hte function returns. So one option is to dynamically allocate the memory..
char * recmsg()
{
char * array = new char[128];
return array;
}
Just remember to clean it up with delete this way (or free if you used malloc). Second, you could use a parameter...
void recmsg(char * message, int size)
{
if (message == 0)
message = new char[size];
}
Again, the same thing goes for clean up here as with the previous. Also note the check for 0 to make sure you don't call new on a pointer that's been allocated already.
Last, you could use a vector..
std::vector<char> recmsg()
{
std::vector<char> temp;
//do stuff with vector here
return temp;
}
char *recvmsg(){
char *buffer = new char;
cout<<"\nENTER NAME : ";
cin>> buffer;
return buffer;
}
int main(){
char *reply = recvmsg();
cout<<reply;
}
Just to complete the picture:
It is not necessary, to allocate memory with malloc. You can also create the buffer on the stack, but you must create it on a stack frame that lives as long as the consumer of the buffer lives. That was the error of the OP -- when the callee was finished, the buffer was deleted and the caller got a invalid pointer.
So what you can do is this:
void recvmsg(char *buffer, size_t size) {
... do what you want ...
}
void main(void) {
char buffer[1024];
recvmsg(buffer, sizeof(buffer));
}
You could dynamically create the buffer, but then the caller needs to know to free it.
I think it's better to pass in a buffer (assuming recvmsg also fills it)
void recvmsg(char *buffer, size_t size){
}
void main(){
char buffer[1024];
recvmsg(buffer, sizeof(buffer));
}
Even if the caller decides dynamic is better, they will know that they need to free it, and the specific way to do that (free(), delete, delete[], or perhaps something special from a custom allocator)
The problem is that you are returning a pointer to a buffer allocated on the stack. Once the function returns, that buffer is no longer valid.
You are allocating the array on the stack inside of your recvmsg function. Returning a pointer to that memory will at some point lead to undefined behavior if it is dereferenced as the memory will be cleaned up when the function exits.
If you want to return a pointer to memory you will need to allocate it dynamically using malloc.
when you are returning the buffer then as it acting as a pointer to the first location of the array so it will return its address.And the place where you are calling the function there you can make a character pointer which will store this returned address value .After which you can move your pointer and can access all the elements of your array.
how about passing by ref
char buf[1024];
PutStuffInBuff(&buf);