I am not a C programmer, so I am not that familiar with C-string but now I have to use a C library so here is a shortened version of my code to demonstrate my problem:
char** ReadLineImpl::my_completion () { char* matches[1]; matches[0] = "add"; return matches; }
I am getting this warning:
Warning - address of stack memory associated with local variable 'matches' returned
And my program does not seem to work properly (might be because of the above mentioned warning).
What does the warning imply? and will it cause any problems?
C++ How to return a local variable from a function? But there is a way to access the local variables of a function using pointers, by creating another pointer variable that points to the variable to be returned and returning the pointer variable itself.
Every time a function is called, the machine allocates some stack memory for it. When a new local variables is declared, more stack memory is allocated for that function to store the variable. Such allocations make the stack grow downwards.
Variable char* matches[1];
is declared on stack, and it will be automatically released when current block goes out of the scope.
This means when you return matches
, memory reserved for matches
will be freed, and your pointer will point to something that you don't want to.
You can solve this in many ways, and some of them are:
Declare matches[1]
as static
: static char* matches[1];
- this will allocate space for matches
in the static space and not on the stack (this may bite you if you use it unappropriately, as all instances of my_completion
function will share the same matches
variable).
Allocate space in the caller function and pass it to my_completion
function: my_completion(matches)
:
char* matches[1]; matches = my_completion(matches); // ... char** ReadLineImpl::my_completion (char** matches) { matches[0] = "add"; return matches; }
Allocate space in the called function on heap (using malloc
, calloc
, and friends) and pass the ownership to the caller function, which will have to deallocate this space when not needed anymore (using free
).
When you return the matches
array, what you are returning is the address of the first element. This is stored on the stack inside my_completion
. Once you return from my_completion
that memory is reclaimed and will (most likely) eventually be reused for something else, overwriting the values stored in matches
- and yes, that may well be why your application doesn't work - if it isn't right now, it probably will be once you have fixed some other problems, or changed it a bit, or something else, because this is not one of those little warnings that you can safely ignore.
You can fix this in a few different ways. The most obvious is to simply use std::vector<char *>
[or better yet std::vector<std::string>
] instead:
std::vector<std::string> ReadLineImpl::my_completion () { std::vector<std::string> strings; strings.push_back("add"); return strings; }
Edit: So, if the library requires a char **
as per the readline
interface,then use this:
char** ReadLineImpl::my_completion () { char **matches = static_cast<char **>malloc(1 * sizeof(char *)); matches[1] = "add"; return matches; }
Problem solved!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With