سؤال

هذا من مكتبة صغيرة وجدتها على الإنترنت:

const char* GetHandStateBrief(const PostFlopState* state)
{
    static std::ostringstream out;

    // ... rest of the function ...

    return out.str().c_str()
}

في الكود الخاص بي أفعل هذا:

const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;

الآن ، في البداية d تحتوي على القمامة. ثم أدركت أن سلسلة C التي أحصل عليها من الوظيفة يتم تدميرها عندما تعود الوظيفة بسبب std::ostringstream يتم تخصيصه على المكدس. لذلك أضفت:

return strdup( out.str().c_str());

والآن يمكنني الحصول على النص الذي أحتاجه من الوظيفة.

لدي سؤالان:

  1. هل أفهم هذا بشكل صحيح؟

  2. لاحظت ذلك لاحقًا out (من النوع std::ostringstream) تم تخصيصها مع التخزين الثابت. ألا يعني هذا أنه من المفترض أن يبقى الكائن في الذاكرة حتى ينتهي البرنامج؟ وإذا كان الأمر كذلك ، فلماذا لا يمكن الوصول إلى السلسلة؟

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

المحلول

يخصص Strdup نسخة من السلسلة على الكومة ، والتي عليك تحريرها يدويًا لاحقًا (مع free() أظن). إذا كان لديك الخيار ، فسيكون من الأفضل للعودة std::string.

التخزين الثابت ل out لا يساعد ، لأن .str() يعيد مؤقتًا std::string, ، والذي تم تدميره عندما تخرج الوظيفة.

نصائح أخرى

أنت على حق out هو متغير ثابت مخصص على قطاع البيانات. ولكن out.str() هو مؤقت مخصص على المكدس. لذلك عندما تفعل return out.str().c_str() أنت تعيد مؤشرًا إلى البيانات الداخلية الخاصة بـ Stack Treporary. لاحظ أنه حتى لو لم تكن السلسلة متغيرًا مكدسًا ، c_str يتم منح "فقط للبقاء دون تغيير حتى المكالمة التالية إلى وظيفة عضو غير ثابتة لكائن السلسلة."

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

يقوم Strdup () بإرجاع مؤشر Char* الذي يشير إلى الذاكرة على الكومة. تحتاج إلى تحرير () عند الانتهاء من ذلك ، ولكن نعم ، سيعمل ذلك.

المتغير المحلي الثابت std::ostringstream out لا معنى له في هذه الحالة ، ما لم تكن السلسلة التي يتم إرجاعها std :: ثابتة أيضًا ، فإن ملاحظتك تظهر أنها غير صحيحة.

في GetHandStateBrief, ، عامل out لا يحتاج إلى أن يكون ثابتا. تحتاج إلى صريح static string لاستبدال المؤقتة التي تم إنشاؤها في مكالمتك الأصلية إلى out.str():

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top