【问题标题】:How to return local array in C++?如何在 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 没有在赋值中使用。

标签: c++ char return-type


【解决方案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 的引用)。
                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2015-10-30
                • 1970-01-01
                • 2020-03-23
                • 2014-11-22
                • 2022-01-16
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多