في C: لماذا يوجد بنية مخصصة المكدس خارج الوظيفة؟

StackOverflow https://stackoverflow.com/questions/2352260

  •  23-09-2019
  •  | 
  •  

سؤال

وظيفتي:

struct hostent * gethost(char * hostname){
    if(/*some condition under which I want 
         to change the mode of my program to not take a host*/){
       return null
    }
    else{
        struct hostent * host = gethostbyname(hostname);
        return host;
    }
}

بشكل رئيسي:

struct hostent * host = gethost(argv[2]);

(تجاهل أي أخطاء بسيطة في الكود ، أنا أخرج من الذاكرة)

هذا يعمل بشكل جيد. ولا يخبرني فالغريند بأنني أفقد ذكرياتها ، على الرغم من أنني لا أحرر.

لماذا ا؟ اعتقدت أن الأشياء المخصصة على المكدس تختفي مع عودة استدعاء الوظيفة؟ أم ذلك لأنني أعيد المؤشر؟ هل هذا خطير بأي شكل من الأشكال؟

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

المحلول

host لم يتم تخصيصه على المكدس ، فقط مؤشر لها على المكدس. يتم نسخ المؤشر عند إرجاع الوظيفة ، لذلك لا حرج في الكود.

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

نصائح أخرى

إنه جيد ويتسرب لأن المؤشر الذي تم إرجاعه لا يشير إلى البيانات الموجودة على المكدس أو الكومة ، ولكن بعض المتغيرات الثابتة.

http://linux.die.net/man/3/gethostbyname:

قد تعود وظائف gethostbyname () و gethostbyaddr () مؤشرات للبيانات الثابتة ، والتي قد يتم الكتابة عليها من خلال المكالمات اللاحقة. نسخ الهيكل العدوى لا يكفي ، لأنه يحتوي على مؤشرات ؛ نسخة عميقة مطلوبة.

من الدليل:

RETURN VALUE
       The gethostbyname() and gethostbyaddr() functions  return  the  hostent
       structure  or a NULL pointer if an error occurs.  On error, the h_errno
       variable holds an error number.  When non-NULL, the  return  value  may
       point at static data, ...

بعض الذاكرة محجوز في وقت الترجمة (أي داخل الثنائي الكود) للهيكل ، تُرجع الوظيفة مؤشرًا إلى هذه الذاكرة.

حسنًا ، لا يتم تسريب الذاكرة حتى يتم فقد جميع الإشارات إليها ، في مثالك يتم إرجاع المؤشر بحيث لا يزال هناك إشارة إليها.

ومع ذلك ، فإن IMHO هو قرار تصميم سيء في معظم الحالات بالاعتماد على جزء آخر من الكود لإصدار الذاكرة الديناميكية. إذا كانت الوظيفة تحتاج إلى إرجاع بنية على سبيل المثال ، فيجب على المتصل القيام بذلك وتمرير مؤشر إلى البنية.

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