在C++中调整动态数组大小

3

我有一些代码,结果与预期不符。以下是代码:

#include <iostream>
using namespace std;

int **nums;
int size;

void A(int** arr)
{
        int **resize;
        resize = new int*[size*2];

        for(int i = 0; i < size; i++)
                resize[i] = new int(*arr[i]);

        cout << endl;
        arr = resize;
        size *= 2;
        delete[] resize;

}

int main()
{
        size = 10;
        nums = new int*[size];
        for(int i = 0; i < size; i++)
                nums[i] = new int(i);

        for(int i = 0; i < size; i++)
                cout << *nums[i] << endl;

        A(nums);

        cout << endl;
        for(int i = (size / 2); i < size; i++)
                nums[i] = new int(i);

        for(int i = 0; i < size; i++)
                cout << *nums[i] << endl;

}

据我所知,函数A(int** arr)的功能正常,并且可以调整数组大小。然而,在main()中的最后一个for循环中,当数组打印时,前两个元素不是0和1,就像它应该是的那样。以下是我得到的结果:

0
1
2
3
4
5
6
7
8
9

16331248
16331712
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

空格后的前两个整数每次程序执行时都不同。经过一些调试,我发现在main()中倒数第二个for循环中的迭代器i=13之前,前两个元素正确打印。然后数组中的前两个元素会变成一些大数值。我不确定为什么会发生这种情况,我已经花了几个小时在这个问题上 :( 任何帮助将不胜感激。

2个回答

4

A()没有修改nums指向新数组,即使它这样做了,它也会删除新数组,导致nums指向无效内存。您需要将arr参数声明为引用,并删除旧数组而不是新数组:

void A(int** &arr)
{
    int **resize;
    resize = new int*[size*2];

    for(int i = 0; i < size; i++)
         resize[i] = new int(*arr[i]);

    cout << endl;
    delete[] arr;
    arr = resize;
    size *= 2;
}

我认为,对于你所尝试的内容,你使用了过多的间接引用。尝试删除一层:

#include <iostream>
using namespace std;

int *nums;
int size;

void A(int* &arr)
{
    int *resize;
    resize = new int[size*2];

    for(int i = 0; i < size; i++)
        resize[i] = arr[i];

    cout << endl;
    delete[] arr;
    arr = resize;
    size *= 2;
}

int main()
{
    size = 10;
    nums = new int[size];
    for(int i = 0; i < size; i++)
         nums[i] = i;

    for(int i = 0; i < size; i++)
        cout << nums[i] << endl;

    A(nums);

    cout << endl;
    for(int i = (size / 2); i < size; i++)
        nums[i] = i;

    for(int i = 0; i < size; i++)
        cout << nums[i] << endl;

    delete[] nums;
}

既然你在使用C ++,你应该使用std :: vector而不是原始数组,这样你就可以完全消除A()

#include <iostream>
#include <vector>
using namespace std;

vector<int> nums;

int main()
{
    nums.resize(10);
    for(int i = 0; i < nums.size(); i++)
         nums[i] = i;

    for(int i = 0; i < nums.size(); i++)
        cout << nums[i] << endl;

    nums.resize(nums.size()*2);

    cout << endl << endl;

    for(int i = (nums.size() / 2); i < nums.size(); i++)
        nums[i] = i;

    for(int i = 0; i < nums.size(); i++)
        cout << nums[i] << endl;
}

感谢您详细的回复。 - homegrown

3
首先,您的函数A不会调整任何大小。它会向标准输出打印换行符,将全局变量size乘以2,然后泄漏一些内存。就是这样。
现在,因为它将size乘以2(从10变为20),所以您在这里遇到了一个问题:
for(int i = (size / 2); i < size; i++)
    nums[i] = new int(i);

在这里,您正在尝试访问指针nums所指向的数组的第10到19个元素。但是,nums指向的数组仅有10个元素(编号为0到9),因此您的代码具有未定义的行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接