سؤال

كنت أبحث في مثال هنا:https://blog.parasoft.com/finding-memory-leaks-in-c

#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *string, *string_so_far;
    int i, length;     length = 0;
    for(i=0; i<argc; i++) {
        length += strlen(argv[i])+1;
        string = malloc(length+1);

        /*  * Copy the string built so far. */
        if(string_so_far != (char *)0)
            strcpy(string, string_so_far);
        else *string = '\0';
        strcat(string, argv[i]);
        if(i < argc-1) strcat(string, " ");
        string_so_far = string;
    }
    printf("You entered: %s\n", string_so_far);
    return (0);
}

ونقرأ ذلك عندما ننفذ البرنامج بالوسيطات التالية:

hello this is a test

يشير المتغير string_so_far إلى السلسلة "hello" التي تم تعيينها كنتيجة لتكرار الحلقة السابقة.لكني لا أفهم كيف؟سيكون الشرح خطوة بخطوة مفيدًا حقًا.

ثانيًا، وجدت هذا المثال في المادة الدراسية:

int countPrimes(int n)
{
   PrimeSet *p = new PrimeSet(n);
      return( p->countPrimeNumbers() );
}

قيل أن هناك تسربًا للذاكرة هنا ولكني لا أفهم حقًا كيف، ربما لأنني لست متأكدًا مما يحدث هنا بالضبط.

هل كانت مفيدة؟

المحلول

في المثال الأول تستخدم malloc داخل حلقة لمتغير.ال malloc call يحجز كتلة من الذاكرة ويعيد العنوان الأول للكتلة.تحتاج إلى الحذف للحظر باستخدام free إذا لم تعد في حاجة إليها.إذا كان المبرمج يرغب في توسيع كتلة الذاكرة، فإن البديل الأفضل سيكون realloc.اقرأ المزيد عن realloc في http://www.cplusplus.com/reference/cstdlib/realloc/.

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

int countPrimes(int n){
   PrimeSet p(n);
   return( p.countPrimeNumbers() );
}

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

نصائح أخرى

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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى cs.stackexchange
scroll top