c++ 函数返回包含无用值的数组[已关闭]

slmsl1lt  于 2023-02-10  发布在  其他
关注(0)|答案(3)|浏览(128)

这个问题是由打字错误或无法再重现的问题引起的。虽然类似的问题在这里可能是on-topic,但这个问题的解决方式不太可能帮助未来的读者。
3天前关闭。
Improve this question
我试图在堆上分配一个数组,这样我就可以将它作为一个函数的输出返回,该函数应该反转元素的顺序。然而,当我运行程序时,array1的第一个元素丢失了,并且我在array2的开头得到了垃圾。
另外,由于我使用的是动态内存,所以我必须使用delete命令释放内存,还是因为它在reverseArray函数的本地作用域内而自动删除它?

#include <iostream>

unsigned *reverseArray(unsigned *arr)
{
    unsigned *output = (unsigned*) malloc(sizeof(int)*5);

    for(unsigned i = 0; i < 5; ++i)
        output[i] = arr[5 - i];

    return output;
}

int main()
{
    unsigned array1[5] = {10, 20, 30, 40, 50};

    unsigned *array2 = reverseArray(array1);

    for(unsigned i = 0; i < 5; ++i)
        std::cout << array2[i] << " ";

    std::cout << std::endl;
    
    return 0;
}

我得到的输出是

32751 50 40 30 20
qrjkbowd

qrjkbowd1#

正如评论中所指出的,你的索引是错误的:5-i访问字段5、4、3、2、1。忽略0,更重要的是,访问数组末尾之后的字段。
但是,您可以只使用标准库的std::reverse函数模板,它甚至可以就地操作:

#include <algorithm>
#include <iterator>
#include <iostream>

int main()
{
    unsigned array1[5] = {10, 20, 30, 40, 50};

    std::reverse(std::begin(array1), std::end(array1));

    for(auto const& value: array1)
        std::cout << value << ' ';
    std::cout << '\n';
}

如果你想保留原来的数组,使用std::array,它有一个方便的复制构造函数:

#include <algorithm>
#include <array>
#include <iostream>

int main()
{
    std::array<unsigned,5> const array1{10, 20, 30, 40, 50};
    auto array2 = array1;

    std::reverse(std::begin(array2), std::end(array2));

    for(auto const& value: array1) std::cout << value << ' ';
    std::cout << '\n';
    for(auto const& value: array2) std::cout << value << ' ';
    std::cout << '\n';
}

这样做的优点是不执行动态分配。std::reverse也完全就地操作,因此以后不需要清理任何内容。
如果你有一个在编译时 * 不 * 知道的值数组,就像你的array1一样,你可以使用std::vector,它会在你完成后清理内存。std::reverse也可以使用它。

r1zhe5dt

r1zhe5dt2#

问题出在这一行:

output[i] = arr[5 - i];

由于i将得到值[0,1,2,3,4],因此5 - i将得到值[5,4,3,2,1]。
为了得到所需的从0开始的索引([4,3,2,1,0]),需要减去1

output[i] = arr[4 - i]; // 5 - i - 1
    • 旁注:**

在C中,最好使用std::vector作为动态数组。
除了其他优点之外,它还可以节省手动newdelete(或者mallocfree,尽管在c
中完全不鼓励使用它们,而在极少数情况下需要使用new/delete)的需要(以及潜在的bug)。

kninwzqo

kninwzqo3#

如果你正在写一个C++程序,那么使用运算符new代替C函数malloc
例如

unsigned *output = new unsigned[5];

当不再需要内存时,您应该释放所有分配的内存。
函数具有未定义的行为,因为在此语句中

output[i] = arr[5 - i];

i等于0时,存在对所传递数组之外的内存的访问,因为在这种情况下,语句如下所示

output[0] = arr[5];

此外,函数参数应该具有限定符const,因为传递的数组在函数中不会更改。
在函数中使用幻数5也会使函数无用。
该程序可以如下所示

#include <iostream>
#include <iterator>

unsigned * reverseArray( const unsigned *arr, size_t n )
{
    unsigned *output = nullptr;

    if ( n != 0 )
    {
        output = new unsigned[n];

        for ( std::size_t i = 0; i < n; ++i )
        {
            output[i] = arr[n - i - 1];
        }
    }

    return output;
}

int main()
{
    unsigned array1[] = { 10, 20, 30, 40, 50 };
    const std::size_t N = std::size( array1 );

    unsigned *array2 = reverseArray( array1, N );

    for ( std::size_t i = 0; i < N; i++ )
    {
        std::cout << array2[i] << ' ';
    }
    std::cout << std::endl;
    
    delete [] array2;

    return 0;
}

注意有标准的std::reverse_copy算法可以使用,使用这个算法程序可以看起来如下

#include <iostream>
#include <iterator>
#include <algorithm>    

int main()
{
    unsigned array1[] = { 10, 20, 30, 40, 50 };
    const std::size_t N = std::size( array1 );
    unsigned array2[N];

    std::reverse_copy( std::begin( array1 ), std::end( array1 ),
                       std::begin( array2 ) );

    for ( const auto &item : array2 )
    {
        std::cout << item << ' ';
    }
    std::cout << std::endl;

    return 0;
}

不需要动态分配一个新数组。否则,您可以编写如下代码

#include <iostream>
#include <iterator>
#include <algorithm>    

int main()
{
    unsigned array1[] = { 10, 20, 30, 40, 50 };
    const std::size_t N = std::size( array1 );
    unsigned *array2 new unsigned[N];

    std::reverse_copy( std::begin( array1 ), std::end( array1 ),
                       array2 );

    for ( std::size_t i = 0; i < N; i++ )
    {
        std::cout << array2[i] << ' ';
    }
    std::cout << std::endl;

    delete [] array2;

    return 0;
}

如果需要反转源阵列,请按以下方式使用另一种算法std::reverse

std::reverse( std::begin( array1 ), std::end( array1 ) );

相关问题