0

可能重复:
c++ 警告:局部变量的地址

char* strdup(const char* s)
{
    char dup[strlen(s)];
    for (int i = 0; i<strlen(s); i++)
    {
        dup[i]=s[i];
    }
    return dup;
}

该函数应该保存已向后读取的新数组以及另一个插槽。当我编译它时,我得到错误“警告:返回局部变量'dup'的地址”,当我运行程序时它返回内存地址。

4

8 回答 8

8

char dup[strlen(s)]定义一个局部堆栈变量;this 在函数结束时超出范围,因此之后任何访问它的尝试都将导致未定义的行为

您的选择是:

  1. 使用堆变量(使用 获得new)。你必须delete在某个时候记住它。
  2. 让函数写入调用者提供的现有缓冲区(例如void strdup(char *out, const char *in))。
  3. 使用像 一样的 C++ 结构std::string,它可以为您完成所有艰苦的工作。

由于您已将问题标记为“C++”,因此我强烈推荐选项 #3。

于 2011-03-22T20:40:45.543 回答
1

您的定义指定了一个 char 数组指针作为其返回类型,但您在函数内部初始化了一个 char 数组并尝试返回它。尝试这个:

char* strdup(const char* s)
{
    char *dup = new char[strlen(s)];
    for (int i = 0; i<strlen(s); i++)
    {
        dup[i]=s[i];
    }
    return dup;

}

于 2011-03-22T20:42:37.053 回答
0

dup变量是一个数组,char并且分配在堆栈上而不是堆上(通过newmalloc)。一旦堆栈帧离开(即:函数离开),这就是未定义的内存,很快就会被其他东西覆盖。

你需要dup变成一个char *并使用newmalloc分配必要的内存。

于 2011-03-22T20:41:37.573 回答
0

问题是你永远不会在堆上分配 dup,所以当你退出堆栈帧时,dup 会自动随堆栈帧一起被移除。这意味着不可能有对 dup 的有效引用,因为一旦退出函数,它就不再存在。

于 2011-03-22T20:41:52.820 回答
0

这应该有效:

char* strdup(const char* s)
{
    char* dup = new char[strlen(s)];
    for (int i = 0; i<strlen(s); i++)
    {
        dup[i]=s[i];
    }
    return dup;
}

编辑:完成后,不要忘记使用“删除”来释放内存;)

于 2011-03-22T20:42:02.570 回答
0

你不能返回 dup[] 因为它是一个局部变量,在函数之外不会有效(好吧,它指向的内存将不再有效)。你必须调用 malloc() 之类的东西,它在堆上分配内存(所有应用程序都可以看到空间)

于 2011-03-22T20:42:15.983 回答
0
char* strdup(const char* s)
{
    char dup[strlen(s)]; // defines *local* variable on *stack*
    for (int i = 0; i<strlen(s); i++)
    {
        dup[i]=s[i];
    }
    return dup; // returning dup[0] = dup address
}

您正在返回在堆栈上创建的局部变量的地址。当您从函数返回时,堆栈将被倒回并且您的dup变量消失了。

于 2011-03-22T20:43:46.543 回答
0

线

char dup[strlen(s)];

在 C++ 中不起作用。数组需要在编译时指定一个常量大小;strlen(s) 是一个变量。

就您的实际警告而言,将指向局部变量的指针返回给调用者是一种不好的做法;由于局部变量(在本例中为数组 dup)是在堆栈上分配的,因此当函数返回时,它会被释放,因此返回的指针可能无效。编译器旨在捕获此类错误并标记警告,指出这可能是问题的潜在来源。

于 2011-03-22T20:43:55.133 回答