避免C+中的内存泄漏+;? 我开始在C++中编码,最近遇到了一个问题,我真的不能找到解决的办法,因为我不理解我的错误。
我的程序是用来把开尔文转换成摄氏度的,但它不能连续转换超过3个温度。当我通过4,它给了我正确的转换与内存问题(超出范围?) “xxx”中出错:双重释放或损坏(输出):0x0000000001c94c40 当我输入超过四个温度时,它会给出一些随机数,这可能是其他地址的值 这是我的节目避免C+中的内存泄漏+;? 我开始在C++中编码,最近遇到了一个问题,我真的不能找到解决的办法,因为我不理解我的错误。,c++,arrays,global-variables,C++,Arrays,Global Variables,我的程序是用来把开尔文转换成摄氏度的,但它不能连续转换超过3个温度。当我通过4,它给了我正确的转换与内存问题(超出范围?) “xxx”中出错:双重释放或损坏(输出):0x0000000001c94c40 当我输入超过四个温度时,它会给出一些随机数,这可能是其他地址的值 这是我的节目 #include <iostream> using namespace std; unsigned int NumberT {0}; //Definition of the glo
#include <iostream>
using namespace std;
unsigned int NumberT {0}; //Definition of the global variables
double* Kelvin=new double[NumberT];
double* Celsius=new double[NumberT];
unsigned int i=0;
double* Conversion (double, double, unsigned int) //Conversion function
{
for(unsigned int i=0;i<NumberT;++i)
{
Celsius[i]=Kelvin[i]-273.15;
}
return Celsius;
}
void printTemperatures (double, double, unsigned int) //Print function
{
for(unsigned int i=0;i<NumberT;++i)
{
cout<<"The temperature is "<< Kelvin[i] <<" [K], which is "<< Celsius[i] <<" [C]"<<endl;
}
return;
}
int main () //Main
{
cout<<"How many temperatures do you want to enter?"<<"\n";
cin>>NumberT;
cout<<"What are the temperatures?"<<"\n";
for (unsigned int i=0;i<NumberT;++i)
{
cin>>Kelvin[i];
}
Conversion (Kelvin[i], Celsius[i], NumberT);
printTemperatures (Kelvin[i], Celsius[i], NumberT);
delete [] Celsius;
delete [] Kelvin;
return 0;
}
#包括
使用名称空间std;
无符号整数{0}//全局变量的定义
双精度*开尔文=新双精度[数值];
双倍*摄氏度=新的双倍[数值];
无符号整数i=0;
double*转换(double,double,unsigned int)//转换函数
{
对于(未签名int i=0;i),现代C++中的一个好习惯是永远不要使用手动内存管理——如果你在C++ 11或更高版本代码中看到<代码>新<代码>或<代码>删除>代码,这是代码气味的标志。
使用std::make_shared
/std::make_unique
代替,使用值类型
和std::move
看看赫伯·萨特的最新作品
以你为例
无符号int NumberT{0};//全局变量的定义
双精度*开尔文=新双精度[数值];
在这里创建一个包含0个元素的数组,然后进行大量未分配的内存覆盖,然后尝试释放它。这不起作用
在阅读了std::cin
中的NumberT
之后,将数组分配移动到,它应该会有很大的改进
下一个改进是切换到没有全局变量的功能性风格(您不需要它们)
然后切换到使用std::shared\u ptr进行内存分配时,您的问题是NumberT
是0
。
当您这样做时:
double* Kelvin=new double[0];
未执行初始化,因此指针的值不确定。
写和读这段记忆有着不确定的行为
当您对具有不确定值的指针使用delete[]
时,您的代码可能会崩溃
此问题非常适合使用向量
而不是双[]
数组,因此没有理由不使用此容器提供的动态内存处理功能
使用以下示例:
//Replace arrays with vectors
vector<double> Kelvin;
vector<double> Celsius;
//in your main to read user input
for (unsigned int i=0;i<NumberT;++i)
{
double read;
cin >> read;
Kelvin.push_back(read);
}
//In your conversion function
for (std::vector<double>::iterator it = Kelvin.begin(); it != Kelvin.end(); ++it)
{
Celsius.push_back((*it)-273.15);
}
-当向量
s超出范围时(在main()
的末尾),它们将为您执行delete
操作。正如另一个所说。数组初始化是个问题。
一般来说,由于您不知道元素的初始大小,我会立即考虑向量。在这种情况下,您可以删除“多少元素…”并引入退出字符或解析X分隔的值
当然,使用数组并没有错,但您必须(重新)用正确的大小初始化它们。因此,在您获得NumberT
之后。不过,对于数组与向量,请检查此项
我已经发布了一个使用向量的实现,但仍然基于您的方法
(注意!:此代码效率不高,因为它会进行大量向量复制,也就是说不会引入新概念。请通过引用和std::move自行搜索参数)
#包括
#包括
#包括
std::vector-ToCelcius(std::vector-kelvinValues)//转换函数
{
std::向量Celcius值;
用于(自动值:开氏值)
{
Celcius值。向后推(值-273.15);
}
返回Celcius值;
}
无效打印温度(std::vector kelvinSource,std::vector celsiusSource)//打印函数
{
对于(uint16_t valueIndex=0;valueIndex 执行内存分配时,std::coutNumberT
为0-将全局变量和内存分配移到main
中,首先读取NumberT
的值,然后才执行实际内存分配。您还应正确格式化代码-一旦代码是格式化的。您确实应该使用std::vector
而不是double*
。您分配的数组大小为0。我不记得这样的操作本身是否是未定义的行为,但尝试将数据写入这样的数组肯定是。您永远不应该使用new
,这会使您的编码容易得多,内存泄漏也不太可能。坚持使用值,std::vector
,如果绝对无法避免,请使用std::unique\u ptr
。为什么不使用缩进?C++11中不存在Shamestd::make\u unique
,因此您必须至少在代码中看到一次“new
”)你仍然在使用new
,即使是在可能导致泄漏的地方。真正的std::make_unique
在构建失败时不会泄漏。是的,但这是可以修复的。我切换到c++14,所以这对我来说不再是个问题。@Berkus:没错;这里面有一个new
,而且(正如Nathan指出的)一个坏的。这正是我的观点!@BoundaryPosition我不明白你在暗示什么。make_unique
是c++14的一部分,你不必看到任何新的
,坏的或不坏的。
void Conversion (vector<double> & Kelvin, vector<double> & Celsius);
#include <iostream>
#include <vector>
#include <algorithm>
std::vector<double> ToCelcius(std::vector<double> kelvinValues) //Conversion function
{
std::vector<double> celciusValues;
for (auto value : kelvinValues)
{
celciusValues.push_back(value - 273.15);
}
return celciusValues;
}
void PrintTemperatures(std::vector<double> kelvinSource, std::vector<double> celsiusSource) //Print function
{
for (uint16_t valueIndex = 0; valueIndex < kelvinSource.size(); valueIndex++)
{
std::cout << "The temperature is " << kelvinSource.at(valueIndex) << " [K], which is " << celsiusSource.at(valueIndex)<< " [C]" << std::endl;
}
}
int main() //Main
{
uint16_t numberOfValues;
std::cout << "How many temperatures do you want to enter?" << "\n";
std::cin >> numberOfValues;
std::cout << "What are the temperatures?" << "\n";
std::vector<double> kelvinValues;
double value;
for (uint16_t i = 0; i< numberOfValues; ++i)
{
if (std::cin >> value) {
kelvinValues.push_back(value);
}
continue;
}
auto celciusValues = ToCelcius(kelvinValues);
PrintTemperatures(kelvinValues, celciusValues);
return 0;
}