ParsX.com
پذیرش پروژه از دانشجویی ... تا سازمانی 09376225339
 
   ProfileProfile   Log in to check your private messagesLog in to check your private messages  |  FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups Log inLog in   RegisterRegister 

تخصيص حافظه پويا با تابع malloc

 
Post new topic   Reply to topic    ParsX.com Forum Index -> C/C++ Programming
View previous topic :: View next topic  
Author Message
vahid
بي تو هرگز


Joined: 26 Nov 2004
Posts: 3067
Location: Tehran

PostPosted: Sun Jan 09, 2005 12:55 pm    Post subject: تخصيص حافظه پويا با تابع malloc Reply with quote

تخصيص حافظه پويا با تابع malloc
Memory allocator يا malloc تابعي است در زبان C ‌ براي تخصيص حافظه در زمان اجراي برنامه به پارامترمورد نظر . مزاياي استفاده از اين تابع :
1. ركوردها (استراكچرها) يي كه طور مشخصي ندارند .
2. خواندن تعداد نامشخصي ركورد از بانك اطلاعاتي
3. در لينك ليستها .
برنامه زير را براي مثال در نظر بگيريد :
main()
        {
            char string[1000];
            strcpy (string, "Some text");
        }

برنامه فوق رشته اي بنام string معرفي ميكند با طول 1000 كاراكتر . حال انكه در دستور زيرين ان تنها از 11 كاراكتر استفاده كرده ايم كه بنابراين 989 بايت اضافي اشغال كرده ايم /
نتيجه ميگيريم كه :
اگر داده ما كمتر از 1000 بايت (كاراكتر) باشد حافظه را بيهوده مصرف كرده ايم .
اگر داده هاي ما بيشتر از 1000 بايت باشد برنامه crash ‌ميكند .
حافظه مورد نظر يعني 1000 بايت تا انتهاي اجراي برنامه اشغال خواهد شد كه شايد تنها در يك نقطه از برنامه از اين حافظه استفاده كرده ايم .
بنابراين متوجه ميشويم كه اين نوع تخصيص حافظه براي متغيرهايي كه طول انها قابل تغيير است بشدت بر كارايي و سرعت برنامه تاثير منفي ميگذارد بنابراين بايد روشي باشد كه بتوان بصورت پويا براي داده هايي كه كمتر از 1000 بايت اشغال ميكنند همان مقداري كه اشغال ميكنند را تخصيص داد و يا براي برنامه هايي كه بيشتر از 1000 بايت اشغال ميكنند نيز همان اندازه حافظه تخصيص داد . بنابراين روشي هم خواهيم داشت كه بتواند حافظه تخصيص داده شده را پس از پايان عمليات به حافظه باز گرداند .
void *malloc(size_t size);
char * String;
String = (char *) malloc(1000);

خط اول اعلان تابع است كه اختياري است و ميتوانيد انرا اعلان نكنيد . اما نوع size_t نوعي جديد است كه تا بحال انرا نديده ايد اين نوع در هدر <stddef.h> قرار دارد . شايد فكر كنيد كه لازم باشد كه اين هدر را نيز در برنامه براي شناسايي Size_t وارد كنيد . حال انكه نيازي به اين كار نيست چرا كه هدرهاي <stddef.h>, <stdio.h>, <stdlib.h>, <string.h>, <time.h> ,<wchar.h> بصورت خودكار در C استاندارد وارد ميشوند .
خط دوم اشاره گري به نوع كاراكتر بنام String توليد ميكند /
خط سوم استفاده از تابع malloc را نشان ميدهد . در اين خط يك رشته 1000 كاراكتري به Stirng نسبت داده ميشود . عمليات تبديل نوع بصورت خودكار انجام ميشود ...
#include <stdlib.h>

دستور فوق فايل هدر stdlib را در برنامه include ميكند تابع malloc در اين فايل قرار دارد .
در مثال بالا مقدار 1000 بايت را به String اختصاص داديم حال انكه شايد در كامپايلري يك كاراكتر يك بايت نبود و قانون استاندارد را زير پا گذاشته بود . براي انكه با مشكل مواجه نشويم با يد دستور malloc را به صورت زير تغيير دهيم
String=(char *)malloc(1000*sizeof(char));

نتيجه گرفتيم كه تابع malloc يك رشته 1000 كاراكتري را به Stirng اختصاص ميدهد .
parsx=(int *)malloc(10*sizeof(int));

دستور فوق يك ارايه 10 كاراكتري از نوع int ‌رابراي parsx مشخص ميكند .
Back to top
arash
مدير بخش سي
مدير بخش سي


Joined: 27 Nov 2004
Posts: 1232
Location: www.parsx.com

PostPosted: Sat Nov 05, 2005 8:08 pm    Post subject: Reply with quote

متغییرهای پویا فضایی از Ds= Data Segment یا SS=Stack Segment که اندازه هر کدام از این سگمنتها حداکثر 64 کیلو بایت است اشغال نمی کند.
بقیه حافظه RAM که در اختیار برنامه نبوده و آزاد می باشد را حافظه Heap یا حافظه پویا می نامند .
calloc :
فرم کلی تابع به صورت زیر است :
void *calloc(unsigned n , unsigned size);

این تابع فضایی به اندازه n*size را از حافظه Heap گرفته و آدرس شروع این فضا را بر می گرداند . مشابه تابع malloc از آنجا که خروجی این تابع از نوع * void است ، باید خروجی این تابع type cast ( تعیین نوع ) شود . اگر در Heap فضای کافی به اندازه n * size وجود نداشته باشد این تابع مقدار NULL بر می گرداند . مثلا دستور زیر :
int *p;
p=(int *)calloc(50,sizeof(float));

به اندازه 4*50 یعنی 200 بایت فضا می گیرد ( جهت آرایه ای 50 خانه ای از نوع float )
realloc :
فرم کلی تابع realloc به صورت زیر است :
void *realloc(void *p , unsigned newsize);

این تابع برای متغییرهای پویا ( که آرگمان اول به آن اشاره می کند ) دوباره فضایی جدید در نظر می گیرد ( به اندازه آرگمان دوم ) و اشاره گری به این محل جدید را باز می گرداند . مکان جدید ممکن است متفاوت با مکان قبلی متغییر بر روی RAM باشد ، در هر حال محتویات آن متغییر پویا را در مکان جدید کپی می کند . اگر حافظه پویا به اندازه کافی newsize فضا نداشته باشد علاوه بر اینکه مقدار NULL برمی گرداند اطلاعات قبلی نیز از بین می رود.

char *s;
s=(char *)malloc(10)
strcpy(s,"Parsx");
printf("%s %p \n",s,s);    => Parsx 050E
s=(char *) realloc (s,20); => الزامی نیست  (Char *) نوشتن
printf("%s %p \n",s,s);    => Parsx 05Ec
free(s);

نکته 1 Exclamation:
توابع calloc و realloc جزو توابع استاندارد ANSI می باشند .
نکته 2 Exclamation:
تابع calloc فضایی را که در حافظه Heap رزرو می کند ، همه را با صفر پر می کند ولی فضایی که توسط تابع malloc رزرو می شود با صفر پر نمی گردد .
نکته 3 Exclamation:
برای رها سازی فضاهای گرفته شده توسط calloc و realloc می توان از تابع free استفاده کرد.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    ParsX.com Forum Index -> C/C++ Programming All times are GMT + 3.5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum