为什么必须动态分配扩展数组才能使此函数正常工作C ++

问题描述 投票:1回答:1

我一直在研究一个接受数组和数组大小作为参数的函数。函数任务是创建第二个数组,该数组的大小是第一个数组的两倍,将第一个数组的元素复制到第二个数组的前半部分,并将其余元素初始化为零。

我只有在函数中动态分配第二个数组时,才能使它起作用。我怀疑这是因为一旦函数将控制权返回给调用函数,所有未动态分配的数组都会从内存中删除。换句话说,调用函数中的指针将指向垃圾数据,因为在扩展器函数中创建的第二个数组现在消失了。有人可以确认吗?

这里是用两种不同方式编写的函数。

这种方式有效

int *array_expander(int array[], int size)
{

    int *new_array = new int[size*2];

    for(int i{0}; i < size; i++)
        *(new_array + i) = *(array + i);

    for(int i{size}; i < size * 2; i++)
        *(new_array + i) = 0;

    return new_array;
}

这种方式不

int *array_expander(int array[], int size)
{
    int new_array[size * 2];

    for(int i{0}; i < size; i++)
        *(new_array + i) = *(array + i);

    for(int i{size}; i < size * 2; i++)
        *(new_array + i) = 0;

    int *arr_ptr = new_array;

    return new_array;
}
c++ arrays memory-management scope
1个回答
1
投票

你是对的。您可能无法从函数返回具有自动存储持续时间的本地对象的指针,因为由于退出该函数后该本地对象将不活动,因此返回的指针将无效。

而且可变长度数组不是标准的C ++功能。所以这条语句

int new_array[size * 2];

不能由没有自己相应语言扩展名的编译器编译。

关于应该声明的功能,如

int * array_expander( const int array[], size_t size );

您应该将限定符const添加到第一个参数,因为传递的数组在函数中没有更改。

该功能可以通过使用标准算法来实现,如下面的演示程序所示。

#include <iostream>
#include <algorithm>

int * array_expander( const int array[], size_t size )
{
    int *new_array = new int[ 2 * size ];

    std::fill_n( std::copy( array, array + size, new_array ), size, 0 );

    return new_array;
}

int main() 
{
    int a[] = { 1, 2, 3, 4, 5 };
    const size_t N = sizeof( a ) / sizeof( *a );

    for ( const auto &item : a ) std::cout << item << ' ';
    std::cout << '\n';

    int *new_array = array_expander( a, N );
    size_t n = 2 * N;

    for ( size_t i = 0; i < n; i++ ) 
    {
        std::cout << new_array[i] << ' ';
    }
    std::cout << '\n';

    delete [] new_array;

    return 0;
}

程序输出为

1 2 3 4 5 
1 2 3 4 5 0 0 0 0 0 

请注意,您可以使用标准容器std::vector而不是数组。

© www.soinside.com 2019 - 2024. All rights reserved.