简体   繁体   English

动态内存寻址和释放

[英]Dynamic memory addressing and deallocation

I'm trying to solve a problem for a web tutorial (non-marked) where I'm implementing a dynamic array. 我正在尝试解决我正在实现动态数组的网络教程(未标记)的问题。 However, it fails in two places: 但是,它在两个地方失败:

  1. Where I try to delete a dynamic array in function ResizeDynamicArray(...) 我尝试在函数ResizeDynamicArray(...)删除动态数组的ResizeDynamicArray(...)
  2. It is outputting incorrect data. 输出的数据不正确。 I expect to see: 我希望看到:

     10 20 30 40 50 10 30 40 50 10 30 50 

    ...but I get this instead: ...但是我得到了这个:

     8723216 8716480 701955994 201375930 10 8723216 701955994 201375930 10 8723216 701955994 10 

Requirements of the solution are: 解决方案的要求是:

  • Use pointer to pointer instead of reference to pointer (btw I have successfully implemented a reference to pointer solution, but I am trying to figure out the pointer to pointer solution) 使用指向指针的指针而不是指向指针的指针 (顺便说一句,我已经成功实现了指向指针解决方案的引用 ,但是我正在尝试找出指向指针解决方案的指针
  • No use of malloc / free 不使用malloc / free
  • No use of vector s 不使用vector
  • Must use the declarations as shown 必须使用如下所示的声明

Could someone please suggest what I'm doing wrong? 有人可以建议我做错了吗?

int* CreateDynamicArray(int capacity, int &size);
void DeleteDynamicArray(int* dynamicArray, int &size);
void InsertElement(int* dynamicArray, int element, int &size, int &capacity);
void DeleteElement(int* dynamicArray, int elementIndex, int &size);
void ResizeDynamicArray(int** dynamicArray, int newCapacity);
void PrintArray(int *ptrArray, int capacity);

#include <iostream>

int main()
{
    int size = 0;
    int capacity = 0;

    int* ptrArray = CreateDynamicArray(capacity, size);

    InsertElement(ptrArray, 10, size, capacity);
    InsertElement(ptrArray, 20, size, capacity);
    InsertElement(ptrArray, 30, size, capacity);
    InsertElement(ptrArray, 40, size, capacity);
    InsertElement(ptrArray, 50, size, capacity);
    PrintArray(ptrArray, size);

    DeleteElement(ptrArray, 1, size);
    PrintArray(ptrArray, size);
    DeleteElement(ptrArray, 2, size);
    PrintArray(ptrArray, size);

    DeleteDynamicArray(ptrArray, size);

    ptrArray = nullptr;

    return 0;
}


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


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


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


void DeleteElement(int* dynamicArray, int elementIndex, int &size)
{
    for(int i = elementIndex + 1; i < size; i++)
        dynamicArray[i - 1] = dynamicArray[i];
    size--;
}


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


void PrintArray(int *dynamicArray, int size)
{
    for (int i = 0; i < size; i++) {
        std::cout << dynamicArray[i] << " ";
    }
    std::cout << std::endl;
}

Let's look at the problem in InsertElement . 让我们看一下InsertElement中的问题。 You have: 你有:

void InsertElement(int* dynamicArray, int element, int &size, int &capacity)
{
    ...
    ResizeDynamicArray(&dynamicArray, capacity);
    ...
}

In this function, you modify what dynamicArray points locally in the function. 在此函数中,您可以修改dynamicArray在函数中本地指向的内容。 That does not change what the pointer points to in the calling function. 这不会改变指针在调用函数中指向的内容。 As a consequence, you have the following problems. 结果,您有以下问题。

  1. The variable in the calling function does not point to the newly allocated memory you expected it to have. 调用函数中的变量未指向您期望它具有的新分配的内存。
  2. The calling function uses memory it doesn't have, causing undefined behavior. 调用函数使用它没有的内存,从而导致未定义的行为。
  3. You have a memory leak. 您有内存泄漏。 The memory acquired in the function is lost to the program as soon as you return from InsertElement . InsertElement返回后,函数中获取的内存将立即丢失给程序。

The way to fix it would be to pass the pointer by reference. 解决该问题的方法是按引用传递指针。

void InsertElement(int*& dynamicArray, int element, int &size, int &capacity)
{
    ...
    ResizeDynamicArray(&dynamicArray, capacity);
    ...
}

I would recommend changing ResizeDynamicArray to also accept a pointer by reference. 我建议更改ResizeDynamicArray以也通过引用接受一个指针。 Using a int** is C-style, not C++ style. 使用int**是C样式,而不是C ++样式。 If you did change that, you can use 如果您确实进行了更改,则可以使用

    ResizeDynamicArray(dynamicArray, capacity);

above. 以上。

Here's my suggestion for the function declarations. 这是我对函数声明的建议。 I take it that you can update the implementations accordingly. 我认为您可以相应地更新实现。

int* CreateDynamicArray(int capacity, int &size);
void DeleteDynamicArray(int*& dynamicArray, int &size);
void InsertElement(int*& dynamicArray, int element, int &size, int &capacity);
void DeleteElement(int* dynamicArray, int elementIndex, int &size);
void ResizeDynamicArray(int*& dynamicArray, int newCapacity);
void PrintArray(int *ptrArray, int capacity);

I noticed that you have a bug in ResizeDynamicArray . 我注意到您在ResizeDynamicArray有一个错误。 You are using: 您正在使用:

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

to copy values from the old array to the new array. 将值从旧数组复制到新数组。 However, the old array does not have as many elements as the new array. 但是,旧数组没有新数组那么多的元素。 You end up copying values from memory that you are not supposed to access. 您最终会从不应访问的内存中复制值。 It will be necessary to pass the old capacity to the function as an argument so you can copy the old values correctly. 有必要将旧容量作为参数传递给函数,以便您可以正确复制旧值。

I believe I have the solution, thanks to R Sahu. 感谢R Sahu,我相信我有解决方案。

int* CreateDynamicArray(int capacity, int &size);
void DeleteDynamicArray(int* dynamicArray, int &size);
void InsertElement(int** dynamicArray, int element, int &size, int &capacity);
void DeleteElement(int** dynamicArray, int elementIndex, int &size);
void ResizeDynamicArray(int** dynamicArray, int newCapacity);
void PrintArray(int *ptrArray, int capacity);

#include <iostream>

int main()
{
    int size = 0;
    int capacity = 0;

    int* ptrArray = CreateDynamicArray(capacity, size);

    InsertElement(&ptrArray, 10, size, capacity);
    InsertElement(&ptrArray, 20, size, capacity);
    InsertElement(&ptrArray, 30, size, capacity);
    InsertElement(&ptrArray, 40, size, capacity);
    InsertElement(&ptrArray, 50, size, capacity);
    PrintArray(ptrArray, size);

    DeleteElement(&ptrArray, 1, size);
    PrintArray(ptrArray, size);
    DeleteElement(&ptrArray, 2, size);
    PrintArray(ptrArray, size);

    DeleteDynamicArray(ptrArray, size);

    ptrArray = nullptr;

    return 0;
}


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


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


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


void DeleteElement(int** dynamicArray, int elementIndex, int &size)
{
    for (int i = elementIndex + 1; i < size; i++)
        (*dynamicArray)[i - 1] = (*dynamicArray)[i];
    size--;
}


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


void PrintArray(int *dynamicArray, int size)
{
    for (int i = 0; i < size; i++) {
        std::cout << dynamicArray[i] << " ";
    }
    std::cout << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM