动态数组传递给函数

时间:2019-06-30 20:00:13

标签: c++ visual-c++ c++17

我要调整大小的数组有问题。有我的代码:

int main ()
{
    // Build an application here
    int length = 0;
    int size = 0;
    int input;
    bool endAdding = false;

    cout << "Please enter the length of the new array : ";
    cin >> length;

    int* oPtrDynamicArray = CreateDynamicArray (length, size);

    do
    {
        cout << "Add an element (0 to quit) : " << endl;
        cin >> input;
        cout << endl << endl;

        if (input == 0){
            endAdding = true;
        }
        else
        {
            InsertElement(oPtrDynamicArray, input, size, length);
        }
        cout << "The array contains : " << endl;
        for (int i = 0; i < size; i++)
        {
            cout << i << ": [" << oPtrDynamicArray[i] << "]" << endl;
        }
    } while (!endAdding);

    DeleteDynamicArray (oPtrDynamicArray, size);
}

int *CreateDynamicArray (int capacity, int &size)
{
    size = 0;
    return new int[capacity];
}

void DeleteDynamicArray (int *dynamicArray, int &size)
{
    delete[] dynamicArray;
    dynamicArray = nullptr;
    size = 0;
}

void InsertElement (int *dynamicArray, int element, int &size, int capacity)
{
    if (capacity <= size)
    {
        ResizeDynamicArray (&dynamicArray, size+1);
    }

    dynamicArray[size] = element;
    size++;

}

void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
    int ** newArray = new int*[newCapacity];
    for (int i = 0; i < newCapacity; i++) 
    {
        newArray[i] = dynamicArray[i];
    }

    *dynamicArray = *newArray;

    delete[] newArray;
    newArray = nullptr;
}

问题在于,仅当容量<= size,但传递给第一个函数的数组以良好的值传递时,该数组才传递给我的“ InsertElement”函数,然后传递给我的“ ResizeDynamicArray”数组中的异常指针。

示例:

对于3的数组,我有:

array [0] = 1->地址0x0004e300包含值1

array [1] = 2->地址0x00000003包含???

array [2] = 3->地址0x008ffb24包含值2

我真的不明白,如果有人可以向我解释我的错误,那真是太好了。

仅供参考,我不需要向量,这是对动态数组的练习,所以我需要动态数组。

谢谢您的帮助!

3 个答案:

答案 0 :(得分:1)

问题在这里

void InsertElement (int *dynamicArray, int element, int &size, int capacity)
{
    if (capacity <= size)
    {
        ResizeDynamicArray (&dynamicArray, size+1);
    }
    dynamicArray[size] = element;
    size++;
}

调用ResizeDynamicArray时,您正在将声明为参数的dynamicArray指针更改为InsertElement。您不更改main中的oPtrDynamicArray指针。

如果要进行此工作,则需要更改InsertElement以使用双指针(就像ResizeDynamicArray一样)

void InsertElement (int **dynamicArray, int element, int &size, int capacity)
{
    if (capacity <= size)
    {
        ResizeDynamicArray (dynamicArray, size+1);
    }
    (*dynamicArray)[size] = element;
    size++;
}

或者您可以做简单的事情,而只需使用std::vector<int>

现在编辑,因为我看着它的ResizeDynamicArray函数,我发现该函数也是完全错误的。显然,您已经学习了一些与指针有关的知识

ResizeDynamicArray应该是这样

void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
    int * newArray = new int[newCapacity];
    for (int i = 0; i < newCapacity; i++) 
    {
        newArray[i] = (*dynamicArray)[i];
    }

    delete[] *dynamicArray;
    *dynamicArray = newArray;
}

您不是第一个不了解指针的新手。仔细看一下上面的代码,并将其与您的代码进行比较。主要区别在于我的代码使用指针来更改所指向的内容。您的代码试图更改指针本身,这是不正确的。这令人困惑,因为所指向的是另一个指针(动态数组)。

答案 1 :(得分:0)

您的代码中存在几个问题:

首先,在ResizeDynamicArray中,将 pointers 数组分配给ints,而不是ints数组。 int ** newArray = new int*[newCapacity]应该是int *newArray = new int[newCapacity]

第二,解决该问题后,您需要写*dynamicArray = newArray;; 但是您应该在将指针分配给新内存块之前,先释放旧数组

void ResizeDynamicArray (int **dynamicArray, int newCapacity)
{
    int *newArray = new int[newCapacity];
    for (int i = 0; i < newCapacity; i++) 
    {
        newArray[i] = (*dynamicArray)[i];
    }

    delete[] *dynamicArray;
    *dynamicArray = newArray;
}

第三,由于InsertElement可能会调用ResizeDynamicArray(这将带给您一个新的内存块),因此您需要更改最初传递的指针。因此,您需要将指针传递给该函数的指针,就像使用ResizeDynamicArray一样:

void InsertElement (int **dynamicArray, int element, int &size, int capacity)

然后相应地调整身体。

答案 2 :(得分:0)

我知道问题已经回答了,但原因还没有。

您必须记住,指针是通过值传递给函数 的。 函数结束时,指针值它指向的地址丢失。 但是您仍然可以通过取消对指针的引用来更改存储在其指向的地址处的值。

要在函数内部传递指向指针的地址它指向的地址,必须将指针传递给指针。在这种情况下,传递双指针是 通过引用将指针传递给函数的代名词

void Foo(int **ptr) 
{
    // Don't use ptr, changes are lost after function end as ptr is a local copy
    // Use *ptr to change the value of the pointer you passed to the function.
    // Use **ptr to change the value at the address the pointer you passed to the funcion points to
}

在这种情况下,您可以通过取消对双指针的引用一次来更改指针值它指向的地址。这适用于以上答案。