The function below tests if the input string contains a double.
bool is_double(const std::string& str)
{
char* p;
strtod(str.c_str(), &p);
return *p == 0;
}
What happens to pointer p after the function returns?
You have two variables to consider: str and p.
The string str is passed as a const reference, so it's lifetime must be managed outside the scope of this function, so it cannot be leaked by this function.
With the character pointer p, we can consider the pointer itself and what it points to. According to the documentation, it is set to "...point to the first character after the number." Meaning, it points to memory inside the string you've passed; it does not get set to newly allocated memory. Since you're already managing the lifetime of str properly, and nothing new has been allocated, you don't have to free what it points to. The pointer variable itself is created on the stack, so its lifetime is that of the function.
So, no, you're not leaking.
A resource leak happens when you allocate a resource that becomes unreachable outside a certain scope and you didn't free it nor can get back a reference to it, whether that resource is dynamic memory, mutexes, or any other process-bound resource.
In your case, you're creating some variables and using a function that doesn't do any dynamic memory allocation so all of your stuff are in the stack => no memory leak because it's "freed" once you return from the function.
As the pointer is within the scope of your function and not declared as anything global, I believe it will be automatically erased after the execution of the function.
pointer p will is set by the function to the next character in str after the numerical value.
so it won't leak memory
also you can use
bool is_double(const std::string& str)
{
double d;
d = strtod(str.c_str(), NULL);
return d != 0.0;
}
Related
So, for example i have this function:
char* retCharPtr(void) {
char data[15] {"Data is here"};
return data; }
And
char* retCharPtr1(void) {
char *data = new char[15];
strcat(data, "Data is here");
return data; }
Please explain where the data array will be placed if std::cout << retCharPtr1();,
and what if std::cout << retCharPtr();?
And in general, where do the values of variables go when functions return their status (int) and it is not stored anywhere. Are these 4 bytes occupied during the full execution of the program?
I need the function to return an array for cout, without the next call delete, and leaks in memory.
When a function returns a value, that value exists as a local variable within the caller's current scope (whether the caller uses it or not), and will be destroyed when the variable goes out of scope. So, in your examples, the returned char* pointer (but not the data being pointed at) is destroyed on the ; following the << statement.
In retCharPtr(), the array is stored in automatic memory within the function's scope. When retCharPtr() exits, that memory goes out of scope and is destroyed. Thus retCharPtr() returns a dangling pointer to invalid memory. If the caller tries to read data using that pointer, it will invoke undefined behavior.
In retCharPtr1(), the array is stored in dynamic memory, and will exist until the memory is explicitly delete[]'ed. If the caller does not call delete[] on the returned pointer, the memory allocated by retCharPtr1() will be leaked.
The solution in both cases is to return a std::string instead of a char*. Let the compiler and std::string manage the memory for you.
This is from a small library that I found online:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ... rest of the function ...
return out.str().c_str()
}
In my code I am doing this:
const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;
Now, at first d contained garbage. I then realized that the C string I am getting from the function is destroyed when the function returns because std::ostringstream is allocated on the stack. So I added:
return strdup( out.str().c_str());
And now I can get the text I need from the function.
I have two questions:
Am I understanding this correctly?
I later noticed that out (of type std::ostringstream) was allocated with static storage. Doesn't that mean that the object is supposed to stay in memory until the program terminates? And if so, then why can't the string be accessed?
strdup allocates a copy of the string on the heap, which you have to free manually later (with free() I think). If you have the option, it would be much better to return std::string.
The static storage of out doesn't help, because .str() returns a temporary std::string, which is destroyed when the function exits.
You're right that out is a static variable allocated on the data segment. But out.str() is a temporary allocated on the stack. So when you do return out.str().c_str() you're returning a pointer to a stack temporary's internal data. Note that even if a string is not a stack variable, c_str is "only granted to remain unchanged until the next call to a non-constant member function of the string object."
I think you've hit on a reasonable workaround, assuming you can't just return a string.
strdup() returns a char* pointer that is pointing to memory on the heap. You need to free() it when you're done with it, but yes, that will work.
The static local variable std::ostringstream out makes no sense in this case, unless the std::string being returned was also static which your observation is showing to be not true.
In GetHandStateBrief, variable out does not need to be static. You need an explicit static string to replace the temporary that was being created in your original call to out.str():
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
I want to know the difference between dynamic memory, stack memory and static memory in C++.
Here is some code as an example:
#include<iostream>
using namespace std;
char *GetMemory(void)
{
char p[]="hello world";
char *q="hello world";
return q;
}
int main(void)
{
return 0;
}
Why is p in the stack memory, but the q in dynamic memory?
p and q are both variables. p is of type "array of 12 char" and q is of type "pointer to char". Both p and q have automatic storage duration. That is, they are allocated on the stack.
q is a pointer and it is initialized to point to the initial character of the string "hello world". This string is a string literal, and all string literals have static storage duration.
p is an array, so when you initialize p with a string literal, it causes p to declare an array of characters, and when it is initialized, the contents of the string literal are copied into the array. So, when GetMemory() is called, space is allocated on the stack for the array p, and the contents of the string literal "hello world" are copied into that array.
No dynamic allocation is performed by your code.
Note that because q is a pointer to an array of characters that have static storage duration, it is safe to return q from the function: the array to which it points will exist for the entire duration of the program. It would not be safe to return p, however, because p ceases to exist when the function returns.
Note also that the type of "hello world" is char const[12]. There is an unsafe implicit conversion in C++ that allows a string literal to be converted to a char* pointing to the initial character of the string literal. This is unsafe because it silently drops the const-qualification. You should always use const char* when handling string literals, because the characters are not modifiable. (In the latest revision of the C++ language, C++11, this unsafe conversion has been removed.)
why is the the "p" in the stack memory but the "q" in the dynamic memory?
That's not true; both p and q are allocated with automatic storage duration (implemented as a stack structure). The differences between them are:
p is an array and points to modifiable memory (stack allocated).
q is a pointer and points to readonly memory that has been allocated statically. You really should have declared it as:
const char *p = "whatever";
There is no dynamic allocation here. You didn't call new, malloc, or some routine which uses those behind the scenes to allocate memory. As a result, it is incorrect to return p from this function as it will be invalid once the function returns.
For your examples, since you are using a string literal, this is likely written into the DATA segment of the executable. There is no dynamic memory allocated. A better example is something like this:
void foo()
{
//This is a stack variable. Space is allocated
//on the stack to store it. Its lifetime is
//the routine that calls it.
some_class stack_variable;
//This is a heap-allocated variable. It will
//remain in memory indefinitely unless deleted.
//If a pointer to this isn't returned, and it
//isn't deleted by the end of the routine, this
//will become a "memory leak".
another_class *heap_variable = new another_class();
//This is a (method) static variable. It retains its
//value between method calls
static int method_static = 1;
++method_static;
}
At the closing brace, stack_variable is cleaned up (that is, the stack space it occupied is reclaimed). heap_variable hasn't been deleted, and thus is a memory leak. If we call this method a few times:
for(int i = 0; i < 5; ++i) { foo(); }
Then method_static will have a value of 5.
In C++ does a pointer remains valid after stack unwinding or not?
It depends on the storage of the pointed-to object. If that object was stack-allocated then the pointer surely becomes invalid - stack unwinding will properly destroy the object. If the object was heap-allocated the pointer only becomes invalid if there's some RAII variable that deallocates the object during stack unwinding.
It depends on what your pointer is pointing to. If it points to heap memory, it still remains valid. If it points to stack memory, it becomes invalid.
No. With stack Unwinding all variables/pointers that are declared in the scopes of the unwounded part of the stack get destroyed.
Also, the rule takes in to consideration the Storage Type of the variables.
for eg: A static variable retains its value between function calls, which means it is not destroyed during stack unwinding. This is due to the fact that Static variable are not stored on the stack but on the BSS or Data Segments.
Local variables(Auto storage type) created on stack inside a function will always be destroyed when function returns and stack unwinding takes place.
Pointers allocated with memory on heap will not be destroyed on stack unwinding because they are allocated on Heap and not stack.
One important rule to remember is NEVER return pointers or references to local variables inside a function. The pointer or reference will contain garbage values.
Consider some examples:
void* f1a()
{
void* p = malloc(10);
return p;
}
...is the same as...
void* f1b()
{
return malloc(10);
}
That's fine, as the pointers are to the heap and thus independent of the stack, function calls and programmatic scopes. The pointer value is copied as the function returns.
int* f2()
{
int x;
return &x; // pointer to x - about to become invalid!
}
The above returns a pointer to a variable x on the stack, which will be reclaimed (x lost) when the function returns.
just to state one extra thing which i feel is important
say we have this statement
obj* objptr = new obj(9) //allocate memory on heap and use constructor
if here exception occurs..
the memory heap is relased back....ie no memory leak...
the reason is....
not because of stack unwinding...but because the way the new operator is converted into the following generated code
the try catch statement are implemented in new operator...something like this...
void * operator new(size_t s)
{
try
{
void * ptr=new(malloc (s))sample(); //placement new
ptr->...
}
catch(..)
{
operator delete(ptr); //<= notice here so if an exception occur then first it is caught here which releases the memory
}
}
however if within the object some memory allocation is done that still doesnt get freed..
I have this simple function:
const wchar_t *StringManager::GetWCharTStar(int stringId)
{
std::wstring originalString = StringManager::GetString(stringId);
const wchar_t *retStr = originalString.c_str();
return retStr;
}
At the second line of that function, I have the correct wchar_t*. However, when I go to return, the data switches to garbage data. There are no functions in between. What gives?!
originalString is allocated on the stack. The .c_str() method just returns a pointer to some contiguous internal memory of the wstring object. When the function returns, originalString goes out of scope and is destroyed, therefore the pointer value you return points to deleted memory.
If you need to do this, you should make a copy of the data into memory you allocate with new or malloc(), and then the caller must delete/free() that memory.
You are returning a pointer to a temporary. When originalString goes out of scope, the data your pointer is pointing to is going to be deleted.
std::wstring originalString; is a local variable inside the body of your GetWCharTStar function.
As soon as you leave the scope of the GetWCharTStar() function, this local variable gets destroyed and the pointer you return is no more valid.
The following code might eventually work:
const wchar_t *StringManager::GetWCharTStar(int stringId)
{
const std::wstring& originalString = StringManager::GetString(stringId);
const wchar_t *retStr = originalString.c_str();
return retStr;
}
Provided StringManager::GetString() returns a reference:
const std::wstring& StringManager::GetString(int stringId);
However, this is still risky as it assumes the strings managed by your StringManager class will never be relocated in memory. For example, if StringManager is implemented with the help of an std::vector then as soon as the vector needs to expand, its previous content gets copied elsewhere in a larger memory block and you end up holding a reference to an object that is no more there.
In other words, avoid returning handles to internal data.
The previous answers are mostly correct, except for one little detail. You're not returning a pointer to a destroyed object, you're returning a pointer owned by a destroyed object. When that object was destroyed, the object your pointer was pointing at was destroyed as well.
This is a FAQ. You are returning a pointer to an object that is freed (originalString object) before you actually get to use it.