将"delete"放入循环中的何处
Where to put "delete" in the loop
假设我有以下代码:
int decreasingTest(int number){
int numberOfDigits = 0; do { number /= 10; numberOfDigits++; } while (number != 0);
int *arrayValue = new int[numberOfDigits + 1];
for(int i = numberOfDigits;0<=i;i--){ //acquire digits of number
arrayValue[i] = (number - fmod(number, pow(10, i))) / pow(10, i);
number = fmod(number, pow(10, i));
i--;
}
for (int j = 0; j < sizeOfArray; j++){
if (arrayValue[j + 1] <= arrayValue[j]){
if ((j + 1) == sizeOfArray){
cout << "The number's digits are decreasing." << endl;
return 5;
}
continue;
}
return 0;
}
}
我应该把delete arrayValue[]
放在return 0
之前的行中,放在continue
之后的括号之后,行return 0
之后,还是放在最后一个括号之前的行中?
代码中有三个位置可以从函数返回:
- 在
return 5
线上 - 在
return 0
线上,循环后 - 在右大括号之前,如果外部循环从未执行。
为了不泄漏资源,每执行一次new
调用,必须执行一次delete
调用。在您的情况下,由于您有两个返回点,因此您需要两个delete
调用 - 一个在每个返回点之前。
像您在此处所做的那样手动管理动态内存是有问题的。 很容易忘记删除某些内容,尤其是当您有多个返回点时。 已经构建了许多语言功能和库组件来解决此问题。 像shared_ptr和unique_ptr这样的智能指针会自动管理动态分配资源的销毁,因此您根本不需要编写delete
,并且make_shared
和make_unique
使您能够甚至永远不编写new
。 (注意:make_unique
不在 C++11 标准中,但它很容易编写,并且预计在 C++14 标准中。
由于多种原因,C 样式数组本身也存在问题。 最明显的是它们的固定大小和经常附带的神奇数字。 语言功能和库组件也存在来解决这个问题,我建议作为一项规则,你应该(几乎)永远不要使用 C 风格的数组。 请改用矢量。
在您的情况下,您根本不需要指针。 你只需要一个"向量":
std::vector <int> arrayValue;
for(int i = numberOfDigits;0<=i;i--){ //acquire digits of number
arrayValue.push_front(number - fmod (number, pow(10, i))) / pow(10,i);
//arrayValue[i] = (number - fmod(number, pow(10, i))) / pow(10, i);
number = fmod(number, pow(10, i));
i--;
}
...
对于这种特殊情况,没有理由使用动态内存。不是想变得迂腐,而是动态内存在很多不应该被使用的地方。
[增编(进一步资料和无耻地抢夺可能的观点)]
您可能会认为所需的位数已经在标准库中,因为十进制表示非常普遍。以下内容基于 Hallvard Furuseth 在 Google Group comp.std.c 中的帖子,但我不会从初始位大小计数中扣除符号位,因此它应该适用于有符号和无符号类型。+3 项表示存储因子"1"所需的数字 (log10(1)=0);符号"+"或"-";以及可能的空终止字符。146/485 的因子仅略大于 log10(2)(在任何基数中相当于 log(2)/log(10)),这是从二进制到十进制表示的数字比例因子。如果您发现任何问题,请告诉我。
//Overestimate for number of decimal digits representing an integer of type integerType
//Works for both signed and unsigned integer types
//Includes space for sign ('+' or '-') and for a termination character
//Upper-bounds the function floor(log10(abs(n))) + 3
#define SIZEDIGITS(integerType) (((sizeof(integerType)*CHAR_BIT)*146)/485 + 3)
int8_t:5 位数字 ("+/-127\0")
uint8_t:5 位数字 ('+255\0')
近似值给出 (8*146)/485 + 3 = 5 位数字
int16_t:7 位数字 ('+/-32767\0')
uint16_t:7 位数字 ('+65536\0')
近似给出 (16*146)/485 + 3 = 7 位数字
int32_t:12 位数字 ('+/-2147483647\0')
uint32_t:12 位数字 ("+4294967295\0")
近似值给出 (32*146)/485 + 3 = 12 位数字
int64_t:21 位数字 ("+/-9223372036854775807\0")
uint64_t:22 位数字 ("+18446744073709551615\0")
近似值给出 (64*146)/485 + 3 = 22 位数字
int128_t:41 位数字
uint128_t:41 位数字
近似给出 (128*146)/485 + 3 = 41 位数字
int9999_t(假装):3012 位数字
uint9999_t(假装):3012 位数字
近似给出 (9999*146)/485 + 3 = 3013(一个未使用的字节 - 人类!
(您可能知道也可能不知道的随机奖励事实:base-e 被认为是最有效的实数基数,就我们通常的实数幂和数字表示而言。三元在这方面优于二进制,因为它更接近e。
鉴于您现在拥有的代码结构,您需要将 delete [] arrayValue;
命令放在三个不同的位置(注意,[]
在 arrayValue
之前,而不是在它之后)。您需要将其放在return 5;
正上方的行上,return 0;
正上方的行上,以及最后一个括号的正前方。代码可能会在这三行中的任何一行上退出函数,在这种情况下,您应该在退出函数之前立即释放内存。
或者,您可以将行int *arrayValue = new int[numberOfDigits + 1];
替换为 std::vector<int> arrayValue(numberOfDigits + 1)
,并让编译器为您处理分配/解除分配。
使用智能指针,例如 std::unique_ptr (http://en.cppreference.com/w/cpp/memory/unique_ptr),当指针超出范围时,它会自动释放动态分配的数组。
-
最重要的一点是,几乎从来没有一种情况是你应该再
new
数组了。我强烈建议你在这里使用std::vector
,这样你的int *arrayValue = new int[numberOfDigits + 1];
就会变成:std::vector<int> arrayValue(numberOfDigits + 1);
而且你不需要做其他代码更改。
请注意,在代码可能出错的情况下,例如,假设您的一个pow
抛出并且您离开此函数而不返回,std::vector
仍然会自行清理,这是new
ed 内存无法说的。 -
如果您发现自己处于应该管理自己的记忆的 1% 情况中。一个好的经验法则是永远不要有多个返回语句。它只会使您的代码不可读且不可维护。因此,您应该将最后一个循环更改为:
int result = 0;
int j = 0;
while(j < sizeOfArray - 1 && arrayValue[j + 1] <= arrayValue[j]){
j++;
}
if (j == sizeOfArray - 1){
cout << "The number's digits are decreasing." << endl;
result = 5;
}
delete[] arrayValue;
return result;
应该使用在标头 <memory>
中声明的标准智能指针std::unique_ptr
时。例如
std::unique_ptr<int[]> arrayValue( new int[numberOfDigits + 1] );
在这种情况下,您无需为删除数组而烦恼。
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 正在尝试了解输入验证循环
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 循环后如何继续阅读
- Ardunio UNO解决了多个重叠的定时器循环
- Eigen如何在容器循环中干净地附加矩阵
- 在某些循环内使用vector.push_back时出现分段错误
- 我正在使用嵌套的while循环来解析具有多行的文本文件,但由于某种原因,它只通过第一行,我不知道为什么
- 为什么我的for循环不能正确获取argv
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- while循环中while循环的时间复杂度是多少
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- 为什么在这个代码结束循环中没有得到结束
- 在基于范围的for循环中使用结构化绑定声明
- 用于C++中带有数组和指针的循环
- 循环中的随机函数
- 是什么阻止DOMTimerCoordinator::NextID进入无休止的循环
- 将"delete"放入循环中的何处