如何在 C++ 中返回本地数组?

Posted

技术标签:

【中文标题】如何在 C++ 中返回本地数组?【英文标题】:How to return local array in C++? 【发布时间】:2011-12-07 20:56:38 【问题描述】:
char *recvmsg()
    char buffer[1024];
    return buffer;


int main()
    char *reply = recvmsg();
    .....

我收到警告:

警告 C4172:返回局部变量或临时地址

【问题讨论】:

您应该选择 C ​​或 C++,因为一个好的答案将取决于此。 你想要 C++ 的答案还是只想要 C 的答案? 哦,顺便说一句。 void main 错了。 如果你正在学习 C++ 的东西使用 void main,那很可能是废话。我会推荐a good introductory C++ book。 在调用例程中使用*recvmsg only 的返回作为像strcpy 这样的函数的输入的情况下,可以忽略警告,如函数 return 没有在赋值中使用。 【参考方案1】:

我建议std::vector<char>:

std::vector<char> recvmsg()

    std::vector<char> buffer(1024);
    //..
    return buffer;

int main()

    std::vector<char> reply = recvmsg();

然后,如果您的代码中需要char*,那么您可以随时使用&amp;reply[0]。例如,

void f(const char* data, size_t size) 

f(&reply[0], reply.size());

你就完成了。这意味着,如果您使用的是 C API,那么您仍然可以使用 std::vector,因为您可以将 &amp;reply[0] 传递给 C API(如上所示),并将 reply 传递给 C++ API。

底线是:尽可能避免使用new。如果你使用new,那么你必须自己管理它,当你不需要它的时候你必须delete

【讨论】:

呵呵,OP 确实投票支持c++,所以应该是这样 OP 也可以使用std::string @ThomasMatthews:如果您将数据(char* 类型)概念化为 buffer 而不是 string,那么我相信 @ 987654334@ 比std::string 更清楚地传达了这一点。 .. 或者可以使用using buffer_t = std::vector&lt;char&gt;;(或者可能是using buffer_t = std::string;),然后使用buffer_t;也许这样更合适。 (希望 C++ 有 strong 别名!)【参考方案2】:

你需要动态分配你的 char 数组:

char *recvmsg()
   char* buffer = new char[1024];
   return buffer;

对于 C++ 和

char *recvmsg()
   char* buffer = malloc(1024);
   return buffer;

对于 C.

如果没有动态分配,您的变量将驻留在函数的堆栈中,因此会在退出时被销毁。这就是你收到警告的原因。在堆上分配它可以防止这种情况发生,但你必须小心并通过delete[] 释放内存。

【讨论】:

在 C++ 中使用 new 并不能使其成为 C++ 风格的解决方案。 C++ 风格的解决方案是std::vector&lt;char&gt;,而不是原始指针char* 据我所知,如果您对 c# 或 VB 有任何互操作需求,您不能真正将 std::vector 与 p/invoke 一起使用 malloc( 1024 * sizeof( char ) ) 不是更好吗? @sazary 偏好问题,sizeof char 始终为 1。 没必要,用的是malloc,看karl or mine的回答。【参考方案3】:

警告信息是正确的。您正在返回函数返回后消失的本地数组的地址。

您可以使用动态内存分配来做到这一点:

char *recvmsg()
    char *buffer = (char*)malloc(1024);
    return buffer;

需要注意的是,您需要确保您稍后使用 free() 指针以避免内存泄漏。

或者,您可以将缓冲区传递给函数。

void recvmsg(char *buffer,int buffer_size)
    //  write to buffer


void main()
    char buffer[1024];
    recvmsg(buffer,1024);

这避免了内存分配的需要。这实际上是首选的方法。

【讨论】:

我肯定会建议这个。在 C++ 中,std::vector&lt;char&gt; 是更好的解决方案。这个答案建议使用 C 风格的解决方案,但问题是用 C++ 标记的。 为什么我的印象是它被标记为 C...但是是的,你是对的,矢量是首选。【参考方案4】:

问题是buffer 存在于堆栈中,并在您退出recvmsg 时超出范围。

你可以在堆上分配buffer

char *recvmsg()
  char *buffer = malloc(1024);
  return buffer;

请注意,现在调用者负责处理分配的内存:

void main()
  char *reply = recvmsg();
  free(reply);

【讨论】:

大部分答案都是有效的,但只有你提到了 free()。为了便于阅读,我会在 main() 中的两行之间添加注释:/* do stuff here*/。 +1【参考方案5】:

您有几个选择...您现在的操作方式将导致未定义的行为,因为一旦 hte 函数返回,数组将超出范围。所以一种选择是动态分配内存..

char * recmsg()
 
   char * array = new char[128];
   return array;

请记住以这种方式删除它(或者如果您使用 malloc,则免费)。其次,您可以使用参数...

void recmsg(char * message, int size)

   if (message == 0)
      message = new char[size];

同样,这里的清理与之前的相同。还要注意检查 0 以确保您不会在已分配的指针上调用 new。

最后,你可以使用矢量..

std::vector<char> recmsg()

   std::vector<char> temp;

   //do stuff with vector here

   return temp;

【讨论】:

【参考方案6】:
char *recvmsg()
    char *buffer = new char;
    cout<<"\nENTER NAME : ";
    cin>> buffer;
    return buffer;


int main()
    char *reply = recvmsg();
    cout<<reply;

【讨论】:

【参考方案7】:

只是为了完成图片:

没有必要用 malloc 分配内存。您也可以在堆栈上创建缓冲区,但您必须在堆栈帧上创建它,只要缓冲区的使用者存在。那是 OP 的错误——当被调用者完成时,缓冲区被删除并且调用者得到了一个无效的指针。

所以你可以这样做:

void recvmsg(char *buffer, size_t size) 
   ... do what you want ...


void main(void) 
    char buffer[1024];
    recvmsg(buffer, sizeof(buffer));

【讨论】:

【参考方案8】:

您可以动态创建缓冲区,但调用者需要知道释放它。

我认为最好传入一个缓冲区(假设 recvmsg 也填充它)

void recvmsg(char *buffer, size_t size)



void main()
    char buffer[1024];
    recvmsg(buffer, sizeof(buffer));

即使调用者认为动态更好,他们也会知道他们需要释放它,以及执行此操作的具体方法(free()、delete、delete[],或者可能来自自定义分配器的特殊方法)

【讨论】:

【参考方案9】:

问题是您正在返回一个指向在堆栈上分配的缓冲区的指针。一旦函数返回,该缓冲区就不再有效。

【讨论】:

【参考方案10】:

您在 recvmsg 函数内部的堆栈上分配数组。如果取消引用,返回指向该内存的指针将在某些时候导致未定义的行为,因为当函数退出时内存将被清理。

如果你想返回一个指向内存的指针,你需要使用malloc动态分配它。

【讨论】:

【参考方案11】:

当您返回缓冲区时,因为它充当指向数组第一个位置的指针,因此它将返回其地址。在您在那里调用函数的地方,您可以创建一个字符指针来存储它返回地址值。之后您可以移动指针并访问数组的所有元素。

【讨论】:

【参考方案12】:

通过 ref 怎么样

char buf[1024];
PutStuffInBuff(&buf);

【讨论】:

我猜,karl 的意思是调用者正在提供对 buf 的引用,而被调用者正在填充 buf。因为调用者作为被调用者的寿命更长(buf 也是如此,所以一切正常,只要调用者不返回 buf 的引用)。

以上是关于如何在 C++ 中返回本地数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 ctypes 将数组从 C++ 函数返回到 Python

python 调用c++程序, c++程序如何返回数组给python

你如何在 C++ 中拆分数组?

如何在 C++ 中“返回一个对象”?

C++中如何在一个二维数组中查找某个值

char数组如何存储在C++中?