使用 C 字符串:“与返回的局部变量关联的堆栈内存地址”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18041100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:40:43  来源:igfitidea点击:

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

c++pointersc-strings

提问by khajvah

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:

我不是 C 程序员,所以我对 C 字符串不太熟悉,但我必须使用 C 库,所以这里是我的代码的缩短版本来演示我的问题:

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?

警告是什么,它会导致任何问题吗?

回答by Nemanja Boric

Variable char* matches[1];is declared on stack, and it will be automatically released when current block goes out of the scope.

变量char* matches[1];在栈上声明,当当前块超出作用域时会自动释放。

This means when you return matches, memory reserved for matcheswill be freed, and your pointer will point to something that you don't want to.

这意味着当您返回时matches,保留的内存matches将被释放,并且您的指针将指向您不想要的内容。

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 matchesin the static space and not on the stack (this may bite you if you use it unappropriately, as all instances of my_completionfunction will share the same matchesvariable).

  2. Allocate space in the caller function and pass it to my_completionfunction: 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).

  1. 声明matches[1]staticstatic char* matches[1];- 这将matches在静态空间中而不是在堆栈上分配空间(如果您使用不当,这可能会咬你,因为my_completion函数的所有实例将共享相同的matches变量)。

  2. 在调用者函数中分配空间并将其传递给my_completion函数my_completion(matches)::

    char* matches[1];
    matches = my_completion(matches);
    
    // ...
    
    char** ReadLineImpl::my_completion (char** matches) {
         matches[0] = "add";
    
         return matches;
    }
    
  3. 在堆上的被调用函数中分配空间(使用malloccalloc和朋友)并将所有权传递给调用者函数,当不再需要(使用free)时,调用者函数将不得不释放此空间。

回答by Mats Petersson

When you return the matchesarray, 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_completionthat 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.

当您返回matches数组时,您返回的是第一个元素的地址。这是存放在栈里面的my_completion。一旦您从my_completion该内存中返回并被回收,并且(很可能)最终将被重用于其他用途,覆盖存储在其中的值matches- 是的,这很可能是您的应用程序不起作用的原因 - 如果不是现在,一旦您修复了一些其他问题,或者对其进行了一些更改或其他事情,可能就会发生这种情况,因为这不是您可以放心忽略的那些小警告之一。

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<char *>[或更好的std::vector<std::string>] 代替:

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 readlineinterface,then use this:

编辑:所以,如果库需要一个char **按照readline接口,那么使用这个:

char** ReadLineImpl::my_completion ()
{
    char **matches = static_cast<char **>malloc(1 * sizeof(char *));
    matches[1] = "add";
    return matches;
}

Problem solved!

问题解决了!

回答by Mike Glukhov

Use heap instead of stack

使用堆代替堆栈

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

对于这种情况,最好使用以下方法在堆中分配内存:

int* someDataForParams(void *_params) {

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

    return charCounts;
}

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

96 只是一个字符串长度(只是一个幻数)

回答by Shammel Lee

change

改变

char* matches[1];

to

char *matches = new matches[1];