【问题标题】:Returning integer array from function with no arguments [duplicate]从没有参数的函数返回整数数组[重复]
【发布时间】:2011-08-17 12:53:08
【问题描述】:

可能重复:
Returning local data from functions in C and C++ via pointer

我需要创建一个返回数组的不带参数的函数

我收到错误:“警告:函数返回局部变量的地址”

为了便于阅读,我的代码已经过简化

int * getNums()
{
    int nums[8];
    nums = {1,2,3,4,5,6,7,8};
    return nums;
}

我明白了,当函数结束时指针丢失了,但数组还会被发送吗?如果没有,在函数调用中返回这个不带参数的整数数组的好方法是什么?

提前感谢帮助!

干杯

【问题讨论】:

标签: c++ arrays function pointers return


【解决方案1】:

假装你不知道 C 数组是什么,加入现代 C++ 的世界:

#include <array>
std::array<int, 8> getNums()
{
    std::array<int, 8> ret = {{ 1, 2, 3, 4, 5, 6, 7, 8 }};
    return ret;
}

如果您的编译器太旧而无法提供array&lt;&gt;std::std::tr1:: 实现,请考虑改用boost::array&lt;&gt;。或者,可以考虑使用std::vector&lt;&gt;

【讨论】:

  • 如果std/tr1/boost::array 不可用,那么你可以返回一个包含数组的结构体;这可能比std::vector 更有效,尤其是对于小型数组。
【解决方案2】:

您的数组是一个常规的基于堆栈的局部变量。这意味着当您从函数返回并返回指向它的指针不起作用时,它会消失。您必须使数组的寿命更长,可以通过将其转换为静态变量或将其分配到堆上来完成:

int *getArray {
    static int foo[] = {…};
    return foo;
}

int *getArray {
    int foo[] = calloc(numberOfItems, sizeof(int));
    foo = …;
    return foo;
}

这两种解决方案都有一些含义,您应该在使用其中一种之前了解这些含义。也就是说,静态分配(第一个选项)现在主要是一种好奇心,因为它创建了一种全局变量,并且导致的问题比它解决的问题多。堆分配的数组很常见,但更习惯的是使用参数传递指针来填充,以使接口更明确。在每种情况下,调用者都负责稍后释放分配的内存。

而且,正如其他人所指出的,如果您不坚持使用纯 C 数组,那么还有更好的特定于 C++ 的解决方案。

【讨论】:

  • new'd 对象存储在裸指针中是一个非常的坏主意,您的警告不足以弥补这一点。
  • 对不起,我从 C 解决方案开始,然后注意到 C++ 标签并冒险进入未知领域。我将回到我熟悉的普通 C 示例 :) 感谢您的更正,在这种情况下到底会出现什么问题?
  • 如果你从一个函数中得到一个裸指针,你不知道你是否需要释放它指向的任何东西,如果你知道,你也不知道怎么做。 (它是一个对象还是一个数组?它是newd 还是malloc'd?)每当你处理一个指向需要清理的资源的哑指针时,你就不是异常安全的。为此,您应该使用智能指针,最好使用现成的指针,例如 std::vectorstd::shared_array
【解决方案3】:

每当一个函数退出时,在该函数中创建的所有局部变量都会被丢弃。
您正在创建函数的本地数组,然后返回指向该数组的指针。返回的指针将指向一个已被操作系统回收的内存位置。所以它对你不起作用。
你应该使用向量而不是数组,因为它是 C++

【讨论】:

    【解决方案4】:
    int* getNums()
    {
        static int nums[8];
        nums = {1,2,3,4,5,6,7,8};
        return nums;
    }
    

    它现在应该可以工作了:)

    【讨论】:

    • 制作静态会增加它的生命周期和你的完成:)
    • 希望你的应用是单线程的!
    • 对于 OP 来说,这可能并不明显,这类似于全局变量。即使使用单个线程,您也可能很容易因为“创建”两个数组并将其中一个中的更改反映在另一个中而被烧毁。
    • -1:这确实解决了眼前的问题。然而,这是一个玩具示例,实际使用表明全局变量是通往维护地狱的最短途径。
    【解决方案5】:

    不,数组不会被“发送”。您需要执行以下操作之一:

    • 使用 new 动态创建数组
    • 静态创建数组
    • 将数组作为指针传递给函数
    • 使用 std::vector

    在大多数情况下,最后一个是首选解决方案。

    【讨论】:

    • +1std::vector。 (不过,您可能需要添加 std/boost::array。)
    【解决方案6】:

    您不能在 C++ 中返回简单数组。试试

    int *getNums()
    {
        int *nums = new int[8];
        ...
        return nums;
    }
    

    现在nums 是一个指向堆数组的指针,它将在getNums 返回后继续存在。

    【讨论】:

      【解决方案7】:

      我明白了,函数结束时指针丢失了,但数组还会被发送吗?

      行为未定义。

      在函数调用中返回这个不带参数的整数数组的好方法是什么?

      int nums[8];
      

      num 是驻留在堆栈上的局部变量。您不能返回局部变量的引用。而是使用运算符 new 分配 nums 并记住 delete[] 它。

      int* getNums()
      {
           int *nums = new int[8] ;
           // .....
      
           return nums ;
      }
      
      // You should deallocate the resources nums acquired through delete[] later,
      // else memory leak prevails.
      

      【讨论】:

      • -1 来自我,用于将 new'd 对象存储在裸指针中。
      • @sbi - 请您详细说明您的评论,以便我更正。
      • @Mahesh:在这些情况下,您可以使用智能指针,例如boost::shared_array,而不是手动管理内存。
      • @Naveen - 我只是在暗示 OP 如何返回一个数组。我不太熟悉 boost 库以及如何感谢您的评论。
      • @Mahesh:问题是资源(此处为内存)管理之一。使用裸指针,您将责任放在调用者身上,一旦她完成它,就可以正确返回内存。 强制使用适当的资源管理器(通常是智能指针),否则你会得到脆弱的代码(并且可能会泄漏)。在 C++03 中,您将使用 std::vector&lt;int&gt;
      猜你喜欢
      • 1970-01-01
      • 2015-01-06
      • 1970-01-01
      • 2011-09-19
      • 2021-07-02
      • 1970-01-01
      • 2013-05-12
      • 1970-01-01
      相关资源
      最近更新 更多