C ++ حجم مجموعة تعتمد على الأسباب وظيفة المعلمة تجميع الأخطاء

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

سؤال

ولدي وظيفة بسيطة في الذي أعلنت مجموعة مع حجم اعتمادا على المعلمة التي هي كثافة العمليات.

    void f(int n){
        char a[n];
    };

    int main() {
        return 0;
    }

وهذه قطعة من رمز يجمع غرامة على GNU C ++ ، ولكن ليس على MSVC 2005.

وأحصل على أخطاء ترجمة التالية:

    .\main.cpp(4) : error C2057: expected constant expression
    .\main.cpp(4) : error C2466: cannot allocate an array of constant size 0
    .\main.cpp(4) : error C2133: 'a' : unknown size

وماذا يمكنني أن أفعل لتصحيح هذا؟

و(أنا مهتم في جعل هذا العمل مع MSVC، من دون استخدام جديدة / حذف)

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

المحلول

وماذا كنت قد وجدت واحدة من ملحقات مترجم جنو للغة C ++. في هذه الحالة، فيجوال C ++ هو الصحيح تماما. يجب تعريف المصفوفات في C ++ مع حجم هذا هو وقت الترجمة التعبير المستمر.

وكان هناك ميزة تضاف إلى C في التحديث 1999 إلى أن لغة يسمى صفائف متغير الطول، حيث هذا هو قانوني. إذا يمكنك العثور على مترجم C التي تدعم C99، التي ليس من السهل. ولكن هذه الميزة ليست جزءا من المعيار C ++، لا تسير الأمور التي يمكن ان تضاف في التحديث القادم لمعيار C ++.

وهناك نوعان من الحلول في C ++. الأول هو استخدام الأمراض المنقولة جنسيا :: ناقلات، والثاني هو فقط لاستخدام مشغل new []:

char *a = new char [n];

وبينما كنت أكتب جوابي، وآخر نشر على اقتراح لاستخدام _alloca. وأود أن أوصي بشدة ضد ذلك. كنت فقط أن تبادل غير القياسية واحد، طريقة غير محمول لبعضها البعض تماما كما مترجم محددة.

نصائح أخرى

وأسلوب لديك تخصيص من المكدس هو ز تمديد ++. للقيام يعادل تحت MSVC، تحتاج إلى استخدام _alloca:

char *a = (char *)_alloca(n);

وأنت تستخدم ما هو ليس معيارا. في الواقع هو معيار C ++ C ولكن ليس. كيف غريبة غير ذلك!

وشرح أكثر قليلا، ووقت التشغيل الحجم صفائف كومة ليست جزءا من C ++، ولكن هي جزء من C99، أحدث معيار لC. That's لماذا بعض المجمعين سوف تحصل عليه، في حين لن الآخرين. أوصي الامتناع عن استخدامه، لتجنب مشاكل التوافق مترجم.

وتنفيذ البديل من وظيفة ستكون باستخدام جديدة وحذف، وأرفق strager.

ويمكنك استخدام جديد / حذف تخصيص / تحرير الذاكرة على الكومة. هذا هو أبطأ وربما أكثر عرضة للخطأ من استخدام حرف [ن]، ولكنها ليست جزءا من معيار C ++ بعد، للأسف.

ويمكنك استخدام الطبقة مجموعة بنطاق دفعة لطريقة-استثناء آمن للاستخدام الجديد []. حذف [] ويسمى تلقائيا على في عندما يخرج من النطاق.

void f(int n) {
    boost::scoped_array<char> a(new char[n]);

    /* Code here. */
}

ويمكنك أيضا استخدام الأمراض المنقولة جنسيا :: ناقلات، واحتياطي () بعض بايت:

void f(int n) {
    std::vector<char> a;
    a.resize(n);

    /* Code here. */
}

إذا <م> قيام تريد استخدام شار [ن]، تجميع كرمز C99 بدلا من التعليمات البرمجية C ++.

إذا كنت على الاطلاق ويجب تخصيص البيانات على المكدس لسبب ما، _alloca استخدام أو _malloca / _freea، والتي هي امتدادات المقدمة من يبس MSVC من هذا القبيل.

وقدم متغير مجموعة طول في C99. كانت مدعومة من دول مجلس التعاون الخليجي في ولكن ليس MSVC. وفقا لشخص في فريق MSVC، مايكروسوفت ليس لديها خطة لدعم هذه الميزة في حياتهم ج / C ++ مترجم. واقترح استخدام STD :: ناقلات في تلك الحالات.

ملحوظة أن C99 لا يتطلب أن مجموعة خصصت على المكدس. المترجم يمكن تخصيص على الكومة. ومع ذلك، دول مجلس التعاون الخليجي لا تخصيص مجموعة على المكدس.

وعادة في C (باستثناء المجمعين C99 كما أشار آخرون) وC ++، إذا كنت ترغب في تخصيص الذاكرة على كومة، وحجم ما تريد تخصيص يجب أن يكون معروفا في وقت الترجمة. يتم تخصيص المتغيرات المحلية على المكدس، لذلك مجموعة الذي يعتمد على معلمة وظيفة في وقت التشغيل طول ينتهك هذه القاعدة. كلاين هو الصحيح أن نشير إلى أن استخدام المشغل 'الجديدة' هي طريقة واحدة لحل هذه المشكلة:


char *a = new char [n];

و

و'ا' لا يزال متغير محلي المخصصة على المكدس، ولكن بدلا من كونها مجموعة كاملة (التي لديها طول متغير)، انها مجرد مؤشر إلى مجموعة (والذي هو دائما نفس الحجم، وبالتالي يعرف في الترجمة زمن). يتم تخصيص مجموعة على كومة، والتي عادة ما يلعب نظيره كومة من - المكدس لأشياء مع حجم المعروفة في وقت الترجمة، وكومة هو للأشياء مع حجم غير معروف في وقت الترجمة

هل من المعقول أن استخدام vector<> بدلا من صفيف؟ أو، منذ كنت استبدال char *، وstd::string؟ هذه لا تعمل بشكل جيد مع التحجيم وقت، رغم أنه قد يكون هناك أسباب أخرى عدم استخدامها.

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