可能重复:
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'的地址”,当我运行程序时它返回内存地址。
可能重复:
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'的地址”,当我运行程序时它返回内存地址。
char dup[strlen(s)]
定义一个局部堆栈变量;this 在函数结束时超出范围,因此之后任何访问它的尝试都将导致未定义的行为。
您的选择是:
new
)。你必须delete
在某个时候记住它。void strdup(char *out, const char *in)
)。std::string
,它可以为您完成所有艰苦的工作。由于您已将问题标记为“C++”,因此我强烈推荐选项 #3。
您的定义指定了一个 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;
}
该dup
变量是一个数组,char
并且分配在堆栈上而不是堆上(通过new
或malloc
)。一旦堆栈帧离开(即:函数离开),这就是未定义的内存,很快就会被其他东西覆盖。
你需要dup
变成一个char *
并使用new
或malloc
分配必要的内存。
问题是你永远不会在堆上分配 dup,所以当你退出堆栈帧时,dup 会自动随堆栈帧一起被移除。这意味着不可能有对 dup 的有效引用,因为一旦退出函数,它就不再存在。
这应该有效:
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;
}
编辑:完成后,不要忘记使用“删除”来释放内存;)
你不能返回 dup[] 因为它是一个局部变量,在函数之外不会有效(好吧,它指向的内存将不再有效)。你必须调用 malloc() 之类的东西,它在堆上分配内存(所有应用程序都可以看到空间)
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
变量消失了。
线
char dup[strlen(s)];
在 C++ 中不起作用。数组需要在编译时指定一个常量大小;strlen(s) 是一个变量。
就您的实际警告而言,将指向局部变量的指针返回给调用者是一种不好的做法;由于局部变量(在本例中为数组 dup)是在堆栈上分配的,因此当函数返回时,它会被释放,因此返回的指针可能无效。编译器旨在捕获此类错误并标记警告,指出这可能是问题的潜在来源。