如果未分配 return,是否需要删除或释放动态数组?还是被函数删除了?
Does the the dynamic array need to be deleted or deallocated if the return is not assigned? Or is it deleted by the function?
#include <iostream>
using namespace std;
int *arrExpand(int *arr, int arrSize)
{
int *p = new int [arrSize * 2];
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return p;
}
int main()
{
int mySize = 5;
int myArr[5] = {1,2,3,4,5};
cout << "Array: ";
for(auto v: myArr)
cout << v;
for( int i = 0; i < mySize * 2; i++)
cout << endl << *(arrExpand(myArr,mySize)+i);
//return is not assigned == delete not needed?
return 0;
}
由于 return 未分配,函数是否删除并释放内存?
是否需要释放内存?
简答:是的,需要删除。
如果您使用 new
分配对象,您也应该删除它们。使用普通指针很容易出错并且需要大量的手动工作,这就是为什么 C++ 有几个可用的智能指针,最重要的是 std::unique_ptr
and std::shared_ptr
。在你的情况下 std::unique_ptr
可能是一个选项。
示例:
std::unique_ptr<int[]> arrExpand(int *arr, int arrSize)
{
std::unique_ptr<int[]> p( new int [arrSize * 2] );
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return std::move(p);
}
在您的示例中可以这样使用:
auto result = arrExpand(myArr,mySize);
for( int i = 0; i < mySize * 2; i++)
cout << endl << result[i];
请注意,您应该在 循环之前 存储一次 arrExpand
的结果,否则将在循环的每次迭代中调用该函数,这是非常低效的。
如前所述,您确实需要 delete[]
内存。您只需记住这个简单的规则即可:
delete
everything you new
ed exactly once. The same applies to delete[]
and new[]
.
但是我不同意智能指针的建议。虽然 std::unique_ptr
作为大型旧代码库中原始数组的直接替代品会有一些优势(如 ), the much more natural alternative is std::vector
:
所述
std::vector<int> arrExpand(int *arr, int arrSize)
{
std::vector<int> p (arrSize * 2);
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return p;
}
甚至更好
std::vector<int> arrExpand(const std::vector<int> &arr)
{
std::vector<int> p (arr.size() * 2);
for(int i =0; i < arr.size() * 2; i++)
{ if(i < arr.size())
p[i] = arr[i];
if(i > arr.size())
p[i] = 0;
}
return p;
}
通常(至少我不知道反例)使用 std::vector
作为标准运行时大小的数组是一个很好的主意。一个很好的理由是自动和正确的内存管理。它还带有很多有用的成员函数,包括知道它自己的大小。
#include <iostream>
using namespace std;
int *arrExpand(int *arr, int arrSize)
{
int *p = new int [arrSize * 2];
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return p;
}
int main()
{
int mySize = 5;
int myArr[5] = {1,2,3,4,5};
cout << "Array: ";
for(auto v: myArr)
cout << v;
for( int i = 0; i < mySize * 2; i++)
cout << endl << *(arrExpand(myArr,mySize)+i);
//return is not assigned == delete not needed?
return 0;
}
由于 return 未分配,函数是否删除并释放内存? 是否需要释放内存?
简答:是的,需要删除。
如果您使用 new
分配对象,您也应该删除它们。使用普通指针很容易出错并且需要大量的手动工作,这就是为什么 C++ 有几个可用的智能指针,最重要的是 std::unique_ptr
and std::shared_ptr
。在你的情况下 std::unique_ptr
可能是一个选项。
示例:
std::unique_ptr<int[]> arrExpand(int *arr, int arrSize)
{
std::unique_ptr<int[]> p( new int [arrSize * 2] );
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return std::move(p);
}
在您的示例中可以这样使用:
auto result = arrExpand(myArr,mySize);
for( int i = 0; i < mySize * 2; i++)
cout << endl << result[i];
请注意,您应该在 循环之前 存储一次 arrExpand
的结果,否则将在循环的每次迭代中调用该函数,这是非常低效的。
如前所述,您确实需要 delete[]
内存。您只需记住这个简单的规则即可:
delete
everything younew
ed exactly once. The same applies todelete[]
andnew[]
.
但是我不同意智能指针的建议。虽然 std::unique_ptr
作为大型旧代码库中原始数组的直接替代品会有一些优势(如 std::vector
:
std::vector<int> arrExpand(int *arr, int arrSize)
{
std::vector<int> p (arrSize * 2);
for(int i =0; i < arrSize * 2; i++)
{ if(i < arrSize)
p[i] = arr[i];
if(i > arrSize)
p[i] = 0;
}
return p;
}
甚至更好
std::vector<int> arrExpand(const std::vector<int> &arr)
{
std::vector<int> p (arr.size() * 2);
for(int i =0; i < arr.size() * 2; i++)
{ if(i < arr.size())
p[i] = arr[i];
if(i > arr.size())
p[i] = 0;
}
return p;
}
通常(至少我不知道反例)使用 std::vector
作为标准运行时大小的数组是一个很好的主意。一个很好的理由是自动和正确的内存管理。它还带有很多有用的成员函数,包括知道它自己的大小。