البرمجة

تجنب تسريب الذاكرة في لغة C: إدارة تخصيص الذاكرة وتحريرها في قوائم متسلسلة

في الكود الذي قدمته، يبدو أنك تقوم بقراءة بيانات من ملف نصي وتخزينها في هيكل البيانات Human، ثم تقوم بإضافة هيكل Human إلى قائمة متسلسلة. ومن ثم، تكرر هذا العمل عدة مرات لتعبئة القائمة بعدة هياكل Human.

المشكلة التي تواجهك هي أن جميع الأشخاص في القائمة لديهم نفس الاسم. يحدث ذلك بسبب استخدامك لنوع البيانات char* لتمثيل الاسم في هيكل Human. عندما تقوم بقراءة الاسم من الملف باستخدام fscanf، يتم تخزين عنوان السلسلة في نفس المكان في الذاكرة لجميع الهياكل.

لحل هذه المشكلة، يمكنك تخصيص مساحة في الذاكرة بشكل فردي لكل هيكل Human، ونسخ الاسم إلى هذه المساحة. يمكن القيام بذلك باستخدام وظيفة مثل strdup لتكرار السلسلة وتخصيص مساحة في الذاكرة بحيث تكون فريدة لكل هيكل Human.

اليك تعديل بسيط على الكود:

c
#include #include #include typedef struct human { int age; char* name; } Human; int main() { Human h; FILE *s = fopen("h.txt", "r"); if (s == NULL) { printf("dsdfsf"); } h.name = (char*)malloc(256); // افتراضياً يمكن أن يكون الحد الأقصى للاسم 256 حرفًا، يمكنك تعديله حسب احتياجاتك fscanf(s, "%d", &h.age); fscanf(s, "%s", h.name); // إضافة h إلى قائمة متسلسلة // كرر هذا الكود عدة مرات لملء القائمة بـ 10 بني آدم free(h.name); // لا تنسى حرر المساحة في الذاكرة بعد الانتهاء من استخدامها return 0; }

هذا التعديل يقوم بتخصيص مساحة في الذاكرة للسلسلة باستخدام malloc، ويستخدم fscanf لنسخ الاسم إلى هذه المساحة. وفي النهاية، يتم حرر المساحة في الذاكرة باستخدام free عند الانتهاء من استخدام الهيكل.

المزيد من المعلومات

تحتاج إلى فهم أعمق حول كيفية إدارة الذاكرة وتحكم في تخصيصها وإطلاقها لتجنب مشاكل مثل تلك التي واجهتك. في الشيفرة السابقة، قمت بتخصيص مساحة في الذاكرة باستخدام malloc لتخزين الأسماء. يُفضل دائمًا حرر المساحة المخصصة في الذاكرة بعد الانتهاء من استخدامها باستخدام free لتجنب تسريب الذاكرة.

أيضًا، يُفضل أن تتحقق دائمًا من نجاح عمليات فتح الملف والقراءة باستخدام fopen وfscanf بفحص قيمة المؤشر العائدة. يمكنك استخدام الشروط للتحقق من نجاح العمليات واتخاذ إجراءات مناسبة في حالة الفشل.

أيضًا، إذا كنت تخطط لتخزين الهياكل في قائمة متسلسلة، يمكنك النظر في استخدام هياكل البيانات الديناميّة، مثل الربط الجغرافي، لتسهيل إدارة العناصر بشكل دينامي وتجنب مشاكل التخصيص والتحرير.

إليك مثال توضيحي للكود يأخذ بعين الاعتبار النقاط المذكورة:

c
#include #include #include typedef struct human { int age; char* name; struct human* next; } Human; void freeList(Human* head) { while (head != NULL) { Human* temp = head; head = head->next; free(temp->name); free(temp); } } int main() { Human* head = NULL; for (int i = 0; i < 10; ++i) { FILE* s = fopen("h.txt", "r"); if (s == NULL) { printf("Failed to open file"); freeList(head); return 1; } Human* h = (Human*)malloc(sizeof(Human)); h->name = (char*)malloc(256); // افتراضياً يمكن أن يكون الحد الأقصى للاسم 256 حرفًا h->next = NULL; fscanf(s, "%d", &h->age); fscanf(s, "%s", h->name); // إضافة h إلى قائمة متسلسلة h->next = head; head = h; fclose(s); } // القيام بأي شيء إضافي مع القائمة // تحرير الذاكرة عند الانتهاء freeList(head); return 0; }

هذا المثال يظهر كيفية إنشاء قائمة متسلسلة من الهياكل البيانية Human وكيفية تحرير المساحة في الذاكرة عند الانتهاء.

مقالات ذات صلة

زر الذهاب إلى الأعلى
إغلاق

أنت تستخدم إضافة Adblock

يرجى تعطيل مانع الإعلانات حيث أن موقعنا غير مزعج ولا بأس من عرض الأعلانات لك فهي تعتبر كمصدر دخل لنا و دعم مقدم منك لنا لنستمر في تقديم المحتوى المناسب و المفيد لك فلا تبخل بدعمنا عزيزي الزائر