سی (زبان برنامه‌نویسی)
مدیریت حافظه

یکی از مهم‌ترین کارکردهای یک زبان برنامه‌نویسی، فراهم آوردن امکاناتی برای مدیریت حافظه و مواردی است که در حافظه ذخیره می‌شوند. C سه روش مشخص برای اختصاص حافظه برای اشیاء ارائه می‌دهد:
تخصیص حافظه استاتیک: فضایی برای جسم در زمان کامپایل در دودویی فراهم می‌شود. این اشیاء تا حدودی (یا طول عمر) دارند تا زمانی که باینری که شامل آنها است در حافظه بارگذاری شود.
تخصیص خودکار حافظه: اشیاء موقتی را می‌توان در پشته ذخیره کرد و پس از خارج شدن از بلوکی که در آن اعلام شده است، این فضای به‌طور خودکار آزاد و قابل استفاده مجدد می‌شود.
تخصیص حافظه پویا: بلوک‌های حافظه با اندازه دلخواه را می‌توان در زمان اجرا با استفاده از توابع کتابخانه مانند malloc از منطقه ای از حافظه به نام پشته درخواست کرد. این بلوک‌ها تا زمانی که با استفاده مجدد از عملکرد مجدد کتابخانه یا مجدداً آزاد شوند، برای استفاده مجدد آزاد می‌شوند
تخصیص حافظه خودکار: اشیا موقتی می‌توانند بر روی پشته ذخیره شوند، این فضای اختصاص داده شده به اشیا به صورت اتوماتیک پس از خارج شدن از بلاکی که اشیا در آنها تعریف شده‌اند، آزاد و دوباره قابل استفاده خواهد بود.
تخصیص حافظه پویا: اندازه‌های اختیاری از بلاک‌های حافظه می‌توانند توسط توابع کتابخانه‌ای همانند تابع ()malloc از ناحیه‌ای از رم موسوم به هیپ در هنگام اجرای برنامه درخواست بشود. این بلاک‌های حافظه تا زمانی‌که توسط تابع ()free به سیستم بازگردانده نشوند در حافظه باقی می‌مانند. برای تخصیص حافظه به صورت پویا (دینامیک) باید آدرس بلوک حافظه‌ای که توسط تابع ()malloc گرفته می‌شود را در یک اشاره گر ذخیره کنیم.
این سه رویکرد در موقعیتهای مختلف مناسب است و دارای تبعات مختلفی است. به عنوان مثال، تخصیص حافظه استاتیک اختصاص کمی به سربار دارد، تخصیص خودکار ممکن است کمی بیشتر از سربار باشد و تخصیص حافظه پویا به‌طور بالقوه می‌تواند مقدار زیادی از سربار را برای تخصیص و جابجایی داشته باشد. ماهیت پایدار اشیاء استاتیک برای حفظ اطلاعات حالت در طول فراخوانی‌های عملکردی مفید است، تخصیص خودکار به راحتی قابل استفاده است اما فضای پشته معمولاً بسیار محدودتر و گذرا از حافظه استاتیک یا فضای پشته است و تخصیص حافظه پویا امکان تخصیص مناسب اشیاء را می‌دهد که اندازه فقط در زمان اجرا شناخته شده است. بیشتر برنامه‌های C از هر سه مورد استفاده گسترده‌ای می‌کنند.
در صورت امکان، تخصیص اتوماتیک یا استاتیک معمولاً ساده‌ترین است زیرا ذخیره‌سازی توسط کامپایلر اداره می‌شود، و برنامه‌نویس را از روی خطای بالقوه خطا در اختصاص و آزاد سازی فضای ذخیره‌سازی آزاد می‌کند. با این وجود بسیاری از ساختارهای داده می‌توانند در زمان اجرا تغییر کنند و از آنجا که تخصیص استاتیک (و تخصیص خودکار قبل از C99) باید در زمان کامپایل اندازه ثابت داشته باشد، موقعیت‌های بسیاری وجود دارد که تخصیص پویا لازم است. قبل از استاندارد C99، آرایه‌های اندازه متغیر نمونه متداول این امر بودند. (به عنوان مثال از آرایه‌های اختصاص داده شده پویا به مقاله در مورد malloc مراجعه کنید) برخلاف تخصیص خودکار، که می‌تواند در زمان اجرا با عواقب کنترل نشده از کار بیفتد، عملکردهای تخصیص پویا هنگام ذخیره‌سازی مورد نیاز، نشانه (به صورت مقدار اشاره گر تهی) را برمی‌گردانند. نمی‌توان اختصاص داد (قبل از اینکه برنامه حتی بتواند اجرای آن را شروع کند، معمولاً توسط لینک دهنده یا لودر تشخیص داده می‌شود)
مگر در مواردی که مشخص شده باشد، اشیاء استاتیک حاوی مقادیر نشانگر صفر یا تهی هنگام شروع برنامه هستند. اشیاء اختصاص داده شده به صورت خودکار و پویا فقط درصورتی تنظیم می‌شوند که مقدار اولیه صریحاً مشخص شود. در غیر این صورت آنها در ابتدا مقادیر مشخص نشده‌ای دارند (به‌طور معمول، هر الگوی بیتی که در آن ذخیره می‌شود، حتی ممکن است یک مقدار معتبر برای آن نوع نداشته باشد). اگر برنامه سعی کند به یک مقدار ناشناخته دسترسی پیدا کند، نتایج مشخص نیست. بسیاری از کامپایلرهای مدرن سعی در کشف و هشدار دربارهٔ این مشکل دارند، اما هم مثبت‌های کاذب و هم منفی کاذب می‌تواند رخ دهد.
مسئله دیگر این است که تخصیص حافظه پشته باید با کاربرد واقعی آن در هر برنامه همگام سازی شود تا در استفاده مجدد از آن تا حد امکان استفاده شود. به عنوان مثال، اگر تنها اشاره گر برای تخصیص حافظه پنهان از محدوده خارج شود یا مقدار آن را قبل از بازنویسی بازنویسی کرده باشد () فراخوانی شود، پس از آن حافظه برای استفاده مجدد بعدی قابل بازیابی نیست و در اصل برای برنامه از بین می‌رود، پدیده ای معروف به a نشت حافظه در مقابل، امکان آزادسازی حافظه وجود دارد اما همچنان به آن مراجعه می‌شود و منجر به نتایج غیرقابل پیش‌بینی می‌شود. به‌طور معمول، علائم در بخشی از برنامه به دور از خطای واقعی ظاهر می‌شوند، و پیگیری مشکل را دشوار می‌کند. (چنین مواردی در زبانهایی که جمع‌آوری زباله‌های اتوماتیک دارند بهبود یافته است)