C++程序,内存占用一直增加,最后无法分配内存而中断

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++程序,内存占用一直增加,最后无法分配内存而中断相关的知识,希望对你有一定的参考价值。

栈,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。
我的问题代码如下:
for (int j = 0; j < n; j++)

getForPart(TH,j,thrsdata, thrsGood,src1, src2,dst, ofs_d);

上面说函数内的变量存储在栈上,函数结束,储单元会自动被释放。可是我在执行上面的循环时,通过断点设置发现, getForPart()函数每执行一次,占用内存就会增加30M。而我的理解是函数执行后,内存会被系统自动释放,内存应该不会变化这么大。
是不是函数分配的内存太大,没有分配到栈上,然后内存就不会被自动释放。电脑内存有限,现在不知道如何解决这一问题,求赐教。
注:编译器是VS2013,函数处理的是图像,使用了OpenCV2.4.8,图像在处理之后也手动释放了内存。

getForPart执行时,内部调用了【动态分配内存】的函数,比如malloc,new等,会从“堆”里分配30M空间,这部分空间不会随函数结束而回收,需要自行回收。 参考技术A 那你就直接分配在堆里面试试呗追问

由于图像的创建和管理是借助OpenCV库实现的,自己分配处理起来不方便,处理不好还会出现其它内存问题

动态内存分配(c++)

  1. 内存分配方式

    (1)从静态存储区域分配。内存在编译的时候就已经分配好了,在整个程序执行运行期间一直存在。如:全局变量,static变量。

    (2)在栈上创建。在执行函数时,函数内部的局部变量的存储单元在栈上创建。函数执行结束后局部变量的存储单元自动释放。

    (3)在堆上创建。也称动态内存分配。程序在运行的时候用new或malloc申请任意的内存,程序员自己负责何时用delete或free释放内存。


  2. 我们都知道c语言开辟以及释放空间用malloc和free。而在c++中却用new和delete。。

   这是为什么呢?

   首先,malloc和free是c/c++语言的标准库函数。而new和delete是c++的运算符。它们都是用来动态开辟内存和释放内存。

   对于对象而言,光用malloc和free无法满足动态对象的要求。对象在创建的同时要执行构造函数初始化对象,在消亡之前要调用析构函数清理对象。由于malloc和free是库函数不是运算符,不能够把执行构造函数和析构函数的任务强加到malloc和free。

   所以c++语言需要一个能够完成动态内存分配和初始化工作的运算符new,以及一个清理和释放内存工作的运算符delete。

注:new和delete不是库函数,是运算符。

3. malloc/free与new/delete的联系

(1)动态内存管理的入口

(2)malloc和free是c/c++语言的标准库函数。而new和delete是c++的运算符。

(3)malloc/free动态开辟空间及释放,new/delete动态开辟空间调用构造函数初始化,清理内存之前调用析构函数。

(4)malloc/free手动计算类型大小,返回void *,而new/delete自动计算类型大小,返回对应类型的指针。

4.new和delete

(1)

技术分享

p1:开辟了一个整型空间

p2:开辟了一个整型空间,并初始化为100.

注:new运算符实际上调用了 operator new()函数,而operator new()函数中又调用了malloc函数。

    delete运算符实际上调用了operator delete()函数。而operator delete()函数又调用_free_dbg()函数。

(2)

技术分享

p3:开辟了10个整型空间

   调用10次构造函数以及10次析构函数。

注:new运算符实际上调用了 operator new[]()函数。operator new[]()函数调用了 operator new()函数,而operator new()函数中调用了malloc函数。

 delete运算符实际上调用了operator delete[]()函数。operator delete[]()函数调用了operator delete()函数,而operator delete()函数又调用_free_dbg()函数。


注:malloc/free,new/delete, new[]/delete[]必须匹配,否则内存泄露,程序崩溃。


c++的其他内存管理接口:

void *operator new(size_t size)

void operator delete(size_t size)

void *operator new[](size_t size)

void operator delete[](size_t size)


5.定位new表达式

  在已分配的原始空间上调用构造函数初始化。

  new (place_address) type

  new (palce_address) type (initializer-list)

  place_address必须是一个指针,指向已经分配好的内存。


技术分享

模拟:

A* p = new A[10];

delete[] p;


#include <iostream>


using namespace std;

class A

{

public:

A(int a = 10)

:_a(a)

{

cout<<"A(int a = 10)"<<endl;

}

~A()

{

cout<<"~A()"<<endl;

}

private:

int _a;

};

int main()

{

A* p = (A *)operator new[](10*sizeof(A)+4);

int i = 0;

int count  = 0;

*(int *)p = 10;

A *pStart = (A *)((int *)p+1);

for(i=0;i<10;i++)

{

new((A *)(int *)pStart + i) A(i);

}

count = *(int *)(pStart - 1);

for(i=0;i<count;i++)

{

pStart[i].~A();

}

operator delete[] ((A *)(int *)pStart-1);

return 0;

}

技术分享


以上是关于C++程序,内存占用一直增加,最后无法分配内存而中断的主要内容,如果未能解决你的问题,请参考以下文章

C++动态内存

C++ 动态内存

owvlab运行时环境打开时间长

额外的函数/方法定义会增加程序的内存占用吗?

内存管理

[C++常见面试笔试题汇总] 程序设计基础 - 内存分配sizeof指针篇