Using C-string: “Address of stack memory associated with local variable returned”

余生长醉 提交于 2019-12-03 06:48:07

问题


I am not a C programmer, so I am not that familiar with C-string but new 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 a warning:

Warning - address of stack memory associated with local variable 'matches' returned

And my application does not seem to work properly (might be because of this warning).

What is the warning and will it cause any problems?


回答1:


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:

  1. Declare matches[1] as static: static char* matches[1]; - this will allocate space for matches on heap (this may bite you if you use it unappropriately, as all instances of my_completion function will share the same matches variable).

  2. 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;
    }
    
  3. 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).




回答2:


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!




回答3:


Use heap instead of stack

It's better to allocate memory in heap for this case by using:

int* someDataForParams(void *_params) {

    ...
    int* charCounts = calloc(96, sizeof(char*));
    ...

    return charCounts;
}

96 is just a string length(Just a magic number)




回答4:


change

char* matches[1];

to

char *matches = new matches[1];


来源:https://stackoverflow.com/questions/18041100/using-c-string-address-of-stack-memory-associated-with-local-variable-returned

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!