PDA

View Full Version : سوال: اختصاص دینامیک حافظه و آزاد کردن آن و بررسی صحت با Valgrind



Boris Rozovsky
سه شنبه 04 فروردین 1394, 00:02 صبح
من یک برنامه نوشتم که بطور دینامیک حافظه اختصاص داده میشه و بعد حافظه آزاد میشه. دو تا مسئله وجود داره:


#include <iostream>
using namespace std;

struct Node{
int *Value;
Node * RightNode;
Node * LeftNode;
};

int myfill(Node *node,int n)
{
if(n!=0){
node->RightNode=new Node;
node->LeftNode=new Node;
node->Value=new int;
*(node->Value)=n;
myfill(node->RightNode,n-1);
myfill(node->LeftNode,n-1);
}else{
node=NULL;
}
return 0;
}

int myfree(Node *node,int n)
{
if(node->RightNode!=NULL){
myfree(node->RightNode,n-1);
}
if(node->LeftNode!=NULL){
myfree(node->LeftNode,n-1);
}
delete node->Value;
delete node;
return 0;
}

int main(int argc, char **argv)
{
Node * mynode;
mynode=new Node;
myfill(mynode,3);
cout<<"Allocation OK!\n";
myfree(mynode,3);
cout<<"Free!\n";
return 0;
}


۱) وقتی کد بجایی می رسه که حافظه اختصاص داده میشه حجم اشغالی در رم افزایش پیدا می کنه ( با سیستم مانیتور میشه دید ) ولی وقتی کد بجایی میرسه که حافظه آزاد میشه حجم برنامه در رم تغییر نمی کنه. اصولا این اتفاق صحیح هستش یا نه؟
۲) من برای اینکه ببینم تمام حافظه اختصاص داده شده آزاد میشه یا نه از valgrind استفاده کردم، فضا آزاد می شه ولی یه ارورایی میده:


==7808== HEAP SUMMARY:
==7808== in use at exit: 0 bytes in 0 blocks
==7808== total heap usage: 22 allocs, 22 frees, 388 bytes allocated
==7808==
==7808== All heap blocks were freed -- no leaks are possible
==7808==
==7808== For counts of detected and suppressed errors, rerun with: -v
==7808== ERROR SUMMARY: 24 errors from 20 contexts (suppressed: 0 from 0)


ارور هم اینه: Uninitialised value was created by a heap allocation at 0x4C2B0E0

الان این یعنی اختصاص دینامیک حافظه من اشکال داره؟ تو یه برنامه کامل و پیچیده ممکنه مشکل برام پیش بیاد؟ حل این ارور چطور ممکنه؟

من برنامه نویس حرفه ای نیستم لطفا ساده توضیح بدید.

rahnema1
سه شنبه 04 فروردین 1394, 08:37 صبح
سلام
int *Value را لازم نیست به صورت اشاره گر بنویسید
بهتره سازنده برای کلاس تعریف کنید تا مقادیر اولیه اشاره گر های راست و چپ را به طور پیش فرض NULL کنه
از مخرب استفاده کنید که کار تخریب چپ و راست را به طور اتوماتیک برای شما انجام بده
همچنین می تونستید از سازنده های دیگه هم واسه مقدار دهی اولیه گره های چپ و راست و Value هم استفاده کنید
حافظه هم کاملا آزاد میشه اینجا بعد از اشغال و آزاد شدن حافظه با cin.get یک وقفه ایجاد می کنیم تا بتونید از طریق system monitor مشاهده کنید چه طور آزاد میشه
پارامتر n تابع myfill را برابر یک عدد نسبتا بزرگ مثل 30 یا 40 بذارید و monitor کنید
چون برای کلاس مخرب تعریف کردیم تنها با یک delete کل درخت پاک میشه

#include <iostream>
using namespace std;

struct Node{
int Value;
Node * RightNode;
Node * LeftNode;
Node() : RightNode(NULL), LeftNode(NULL) { }
~Node()
{
delete RightNode;
delete LeftNode;
}
};

int myfill(Node *node,int n)
{
if(n!=0)
{
node->RightNode=new Node;
node->LeftNode=new Node;
node->Value = n;
myfill(node->RightNode, n - 1);
myfill(node->LeftNode, n - 1);
}
}


int main(int argc, char **argv)
{
Node * mynode = NULL;
mynode=new Node;
myfill(mynode,3);
cout<<"Allocation OK!\n";
cin.get();
delete mynode ;
cout<<"Free!\n";
cin.get();
return 0;
}

Boris Rozovsky
سه شنبه 04 فروردین 1394, 12:39 عصر
واقعا از توضیح خوبتون متشکرم.