为了账号安全,请及时绑定邮箱和手机立即绑定

C中局部变量错误的函数返回地址

C中局部变量错误的函数返回地址

C
陪伴而非守候 2019-11-04 12:56:19
我有以下代码: char* gen() {     char out[256];     sprintf(out, ...); // you don't need to know what's in here I don't think     return out; }当我尝试编译时出现此错误:ERROR: function returns address of local variable我试过有这个回报率char[],并char没有运气。我想念什么吗?
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

你的char数组变量out只存在内部函数体。

当您从函数返回时,out缓冲区的内容将无法再访问,它仅是函数的本地内容。


如果要将函数中的某个字符串返回给调用者,则可以在函数内部动态分配该字符串(例如使用malloc()),并将指向该字符串的指针返回给调用者,例如


char* gen(void)

{   

    char out[256];

    sprintf(out, ...);


/* 

 *   This does NOT work, since "out" is local to the function.

 *

 *   return out;

 */


    /* Dynamically allocate the string */

    char* result = malloc(strlen(out) + 1) /* +1 for terminating NUL */


    /* Deep-copy the string from temporary buffer to return value buffer */

    strcpy(result, out);


    /* Return the pointer to the dynamically allocated buffer */

    return result;

    /* NOTE: The caller must FREE this memory using free(). */

}

另一个更简单的选择是将out缓冲区指针char*与缓冲区大小一起作为参数传递(以避免缓冲区溢出)。


在这种情况下,您的函数可以将字符串直接格式化为作为参数传递的目标缓冲区:


/* Pass destination buffer pointer and buffer size */

void gen(char* out, size_t out_size)

{   

    /* Directly write into caller supplied buffer. 

     * Note: Use a "safe" function like snprintf(), to avoid buffer overruns.

     */

    snprintf(out, out_size, ...);

    ...

}

请注意,您在问题标题中明确指出了“ C”,但添加了[c++]标签。如果你可以使用C ++,以最简单的做法是使用一个字符串类像std::string(并让它管理所有的字符串缓冲区的内存分配/清理)。


查看完整回答
反对 回复 2019-11-04
?
茅侃侃

TA贡献1842条经验 获得超21个赞

当您在函数中使用以下声明时,char out[256];一旦函数返回,分配的空间将被释放,因此返回指向out char数组的指针没有任何意义。


如果你想返回一个指向你,你应该使用函数创建一个字符串malloc(),如


char* out = (char*)malloc(256*sizeof(char));

它分配了256 chars的空间,但是应该在某个时候通过free()函数手动释放它。


或如Brian Bi的注释中所建议的,传递a char *指向要用作函数参数的字符串。


查看完整回答
反对 回复 2019-11-04
?
皈依舞

TA贡献1851条经验 获得超3个赞

问题在于,当函数gen返回(退出)时,其局部变量(例如out)超出范围,并且调用者无法再访问它。因此,当您返回时,您将out返回一个指针,该指针不再分配。


有两个选项可从函数“返回”指针/缓冲区:


在调用函数中分配缓冲区,并将其传递给gen:


char out[256];

gen(out, sizeof out);

通常还提供传入的缓冲区的大小,因为被调用的函数无法知道这一点。这意味着您必须将gen的声明更改为:


void gen(char * out, size_t size){

您也可以将传入缓冲区的大小硬编码为256(因为您现在已将其硬编码在gen函数中):


void gen(char out[256]){

这意味着你必须提供类型的变量char[256]来gen(并且没有其他指针或阵列)。但这确实允许您在sizeof out 内部 做gen。


在函数内部动态分配缓冲区:


char * out = malloc(256 * sizeof *out);

// ...

return out;

这样做的好处是gen不会更改声明。但这确实意味着调用函数free完成操作后必须返回缓冲区。


查看完整回答
反对 回复 2019-11-04
  • 3 回答
  • 0 关注
  • 481 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信