【问题标题】:Is this the correct way to allocate and delete dynamic memory in C++?这是在 C++ 中分配和删除动态内存的正确方法吗?
【发布时间】:2018-09-19 11:57:01
【问题描述】:

我有一个班级作业,我需要在其中创建 3 个函数来使用常量参数进行测试。我还应该创建和删除动态内存。我已经附上了作业的确切说明,以防万一,以及我的代码。

如果代码混乱,我深表歉意。我是一名初级程序员,也是该网站的新手,所以我不确定如何完美地格式化所有内容。

任务路线:

编写一个 C++ 程序来测试下面描述的三个使用指针和动态内存分配的函数。

  1. Expand:将一个 int 数组和数组的大小作为参数。它应该创建一个两倍于参数数组大小的新数组。该函数应该将参数数组的内容复制到新数组中,并用 -1 初始化新数组中未使用的元素。该函数应该返回一个指向新数组的指针。

  2. concatenate:将两个 int 数组和数组的大小作为参数(即 4 个参数)。它应该创建一个足够大的新数组来存储两个数组。然后它应该将第一个数组的内容复制到新数组中,然后将第二个数组的内容复制到新数组的剩余元素中,并返回一个指向新数组的指针。

  3. subArray:它接受一个 int 数组、一个起始索引和一个长度作为参数。它创建一个新数组,该数组是原始数组中从起始索引开始的元素的副本,并且长度等于长度参数。例如,subArray(aa,5,4) 将返回一个仅包含元素 aa[5]、aa[6]、aa[7] 和 aa[8] 的新数组。

我的代码:

#include <iostream>

using namespace std;

int* Expand(int [], int);

int* concatenate(int[], int, int[], int);

int* subArray(int[], int, int);

int main()
{
    //Declare variables
    const int SIZEAA = 10;
    const int SIZEBB = 5;
    int aa[SIZEAA] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    int bb[SIZEBB] = { 11, 22, 33, 44, 55 };

    //Output both original arrays
    cout << "aa[10]: ";
    for (int i = 0; i < SIZEAA; i++)
        cout << aa[i] << " ";
    cout << endl;

    cout << "bb[5]: ";
    for (int i = 0; i < SIZEBB; i++)
        cout << bb[i] << " ";
    cout << endl;

    //Call the Expand function
    int* aaExpand = Expand(aa, SIZEAA);

    //Output expanded array
    cout << "Testing Expand: ";
    for (int i = 0; i < 20; i++)
        cout << aaExpand[i] << " ";
    //Release dynamic memory
    delete[] aaExpand;
    aaExpand = nullptr;
    cout << endl;

    //Call the concatenate function
    int* concatenateArray = concatenate(aa, SIZEAA, bb, SIZEBB);

    //Output concatenated array
    cout << "Testing concatenate: ";
    for (int i = 0; i < (SIZEAA + SIZEBB); i++)
        cout << concatenateArray[i] << " ";
    //Release dynamic memory
    delete[] concatenateArray;
    concatenateArray = nullptr;
    cout << endl;

    //Call subArray function
    int* arraySub = subArray(aa, 5, 4);

    //Output the sub array
    cout << "Testing subArray: ";
    for (int i = 0; i < 4; i++)
        cout << arraySub[i] << " ";
    //Release dynamic memory
    delete[] arraySub;
    arraySub = nullptr;
    cout << endl;
}

int* Expand(int aa[], int size)     /*This function takes in an array and 
the size as parameters, creates a new array of double the size, and copies 
the old array into it.It then adds -1 into all new spaces created. 
It returns a pointer to the new array*/
{
    //Declare new array
    int* aaNew;
    int newSize = size * 2;
    aaNew = new int[newSize];

    //Copy old array into new array
    for (int i = 0; i < newSize; i++)
    {
        if (i >= 0 && i < size)     //Check to see if it needs to copy an old value in or put -1 into the array
            aaNew[i] = aa[i];
        else
            aaNew[i] = -1;
    }

    return aaNew;
}

int * concatenate(int aa[], int sizeAA, int bb[], int sizeBB)   /*This 
function takes in two different arrays, creates a new array, then copies 
both arrays into the new array.It returns a pointer to the new array*/
{
    //Create new array size
    int newSize = (sizeAA + sizeBB);

    //Create new array
    int* concatArray;
    concatArray = new int[newSize];

    //Add elements of first and second array into new array
    for (int i = 0; i < newSize; i++)
    {
        if (i >= 0 && i < sizeAA)       //Check to see if a value from the first or second array is supposed to be added
            concatArray[i] = aa[i];
        else
            concatArray[i] = bb[i - sizeAA];
    }

    return concatArray;
}

int * subArray(int a[], int start, int length)    /* This function takes in 
an array, a start value, and a length value. It creates a new array and 
copies the values of the original array starting at the passed start value 
and continues until the new array is the length of the passed length value. 
It returns a pointer to the new array*/
{
    //Create new array size
    int subSize = length;

    //Create a new array
    int* sub;
    sub = new int[subSize];

    //Add elements of original array starting at the passed start value into new 
    array until the new array is the length specified by the argument
    for (int i = 0; i < subSize; i++)
    {
        sub[i] = a[start];
        start += 1;
    }

    return sub;
}

【问题讨论】:

标签: c++ dynamic-memory-allocation


【解决方案1】:

您的设置非常好。很高兴看到你掌握了窍门。但是,您的函数可以使用一些优化。在我们开始之前,我想指出 C++ 有一个 std::vector 类,它可以根据需要动态分配内存并提供许多强大的 mod 函数。我建议您检查一下,因为它会使您的程序更上一层楼。 首先,您的Expand()function 设置得很好。只是一些小的修改:清理你的代码,

int* aaNew;
int newSize = size * 2;
aaNew = new int[newSize];

可以简单地变成:

int newSize = size * 2;
int *aaNew = new int[newSize];

在您的for 循环内,无需检查i 的完整范围,只需检查其上限:

if (i >= 0 && i < size) 

可以变成:

if (i < size) 

这将与您的 if-statement 具有相同的结果,但更优雅,因为 i 永远不会小于 0。

继续前进,您的 concatenate() 函数可能会变得更简单。虽然您所做的在技术上是正确且有效的,但您的 concatenate() 函数可以简化为:

int * concatenate(int aa[], int sizeAA, int bb[], int sizeBB) {

    int * result = new int[sizeAA + sizeBB];
    copy(aa, aa + sizeAA, result);
    copy(bb, bb + sizeBB, result + sizeAA);
    return result;

}

此外,在您的 subArray() 函数中,您可以减少:

//Create new array size
int subSize = length;

//Create a new array
int* sub;
sub = new int[subSize];

到:

//Create new array size
int subSize = length;
int *sub = new int[subSize];

最后,您的主要功能可以使用大修。考虑添加 writeArray() 函数,因为您经常重复该任务:

string writeArray(int ar[], int arLength) {
    string ret = "";
    for (int i = 0; i < arLength; i++)
        ret += " " + to_string(i);
    return ret + "\n";
}

这样你的main() 可以变成:

int main() {

    //Declare variables
    const int SIZEAA = 10, SIZEBB = 5;
    int aa[SIZEAA] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    int bb[SIZEBB] = { 11, 22, 33, 44, 55 };

    //Output both original arrays
    cout << "aa[10]: " << writeArray(aa, SIZEAA);
    cout << "bb[5]: " << writeArray(bb, SIZEBB);

    //Call the Expand function
    int *aaExpand = Expand(aa, SIZEAA);
    cout << "Testing Expand: " << writeArray(aaExpand, SIZEAA * 2);

    //Call the concatenate function
    int *concatenateArray = concatenate(aa, SIZEAA, bb, SIZEBB);
    cout << "Testing concatenate: " << writeArray(concatenateArray,
                                                 (SIZEAA + SIZEBB));

    //Call subArray function
    int *arraySub = subArray(aa, 5, 4);
    cout << "Testing subArray: " << writeArray(arraySub, 4);
    //Output the sub array

    //Release dynamic memory
    delete[] aaExpand;
    delete[] concatenateArray;
    delete[] arraySub;

    aaExpand = nullptr;
    concatenateArray = nullptr;
    arraySub = nullptr;

}

您的程序的其余部分看起来不错。继续努力!

【讨论】:

  • 很高兴提及std::vector,但new/delete 具有教育价值(更不用说您保留对内存分配的控制)。很高兴提及更高级别的数据处理类,但始终鼓励对语言的各个方面有充分的理解。
  • 感谢@DavidC.Rankin 的提示。我就是为了那个!!
  • 你明白了,只是有点不清楚这是推动矢量并远离new/delete,还是提到更多“好事即将到来”。答案真的很努力!
  • @David 使用std::vector,您同样可以很好地控制分配。没有明确的new/delete 和周围的样板代码。
【解决方案2】:
    int* Expand(int elements[], int size)
    {
        int* new_elements = new int[2 * size];

        for (int i = 0; i < size; i++)
        {
            new_elements[i] = elements[i];
            new_elements[i + size] = -1;
        }

        return new_elements;
    }

    int* concatenate(int first[], int firstSize, int second[], int secondSize)
    {
        int* elements = new int[firstSize + secondSize];

        for (int i = 0; i < firstSize; i++)
        {
            elements[i] = first[i];
        }
        for (int j = 0; i < secondSize; j++)
        {
            elements[firstSize + j] = second[j];
        }

        return elements;
    }

    int* subArray(int elements[], int offset, int size)
    {
        int* new_elements = new int[size];

        for (int i = 0; i < size; i++)
        {
            new_elements[i] = elements[offset + i];
        }

        return new_elements;
    }

【讨论】:

  • 一个只显示代码而没有解释为什么它是一个答案的答案并不是一个有用的答案。
猜你喜欢
  • 2019-02-11
  • 2017-05-08
  • 2010-09-30
  • 2013-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
相关资源
最近更新 更多