كيف يمكنني منع الحاجة إلى نسخ السلاسل التي تم تمريرها إلى C-منشئ AVR دول مجلس التعاون الخليجي ++؟

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

سؤال

ArduinoUnit مكتبة وحدة اختبار لقد قدمت آلية لإعطاء TestSuite اسم . ويمكن للمستخدم من المكتبة إرسال ما يلي:

TestSuite suite("my test suite");
// ...
suite.run(); // Suite name is used here

وهذا هو الاستخدام المتوقع - اسم TestSuite هو سلسلة الحرفي. ومع ذلك لمنع بجد لايجاد الخلل أجد نفسي مضطرا لتلبية الاستخدامات المختلفة، على سبيل المثال:

char* name = (char*) malloc(14);
strcpy(name, "my test suite");
TestSuite suite(name);
free(name);
// ...
suite.run(); // Suite name is used here

وعلى هذا النحو لقد نفذت TestSuite مثل هذا:

class TestSuite {
public:
  TestSuite(const char* name) {
    name_ = (char*) malloc(strlen(name) + 1);
    strcpy(name_, name);
  }

  ~TestSuite() {
    free(name_);
  }

private:
  char* name_;
};

وإذا وضعنا جانبا قضية بالفشل في التعامل مع فشل تخصيص الذاكرة في منشئ كنت تفضل ببساطة تخصيص المؤشر لمتغير عضو من هذا القبيل:

class TestSuite {
public:
  TestSuite(const char* name) : name_(name) {
  }

private:
  const char* name_;
};

هل هناك أي طريقة يمكن تغيير واجهة لإجبارها على استخدامها "بشكل صحيح" حتى أستطيع أن نتخلص من تخصيص الذاكرة الديناميكية؟

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

المحلول

وماذا لو كنت توفير اثنين الصانعين مثقلة؟

TestSuite(const char* name) ...
TestSuite(char* name) ...

إذا دعا مع const char*، ثم منشئ يمكن أن تجعل نسخة من مؤشر، على افتراض أن السلسلة لن تذهب بعيدا. إذا دعا مع char*، يمكن للمنشئ جعل نسخة من السلسلة بأكملها.

لاحظ أنه لا يزال من الممكن لتخريب هذه الآلية عن طريق تمرير const char* إلى منشئ عندما name هو في الواقع المخصصة بشكل حيوي. ومع ذلك، وهذا قد يكون كافيا لأغراضك.

وأود أن أشير إلى أنني لم أر في الواقع هذه التقنية تستخدم في API، كان مجرد التفكير التي وقعت لي وأنا أقرأ سؤالك.

نصائح أخرى

والتوثيق. على سبيل المثال،

/**
* Test suite constructor.
* @param name test suite name cstring, shared
*/
TestSuite(char const *name) {
// ...

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

حسنا، يمكنك استخدام الأمراض المنقولة جنسيا :: السلسلة التي سوف تأخذ الرعاية من كل تخصيص الذاكرة

class TestSuite {
public:
  TestSuite(const std::string &name):name_(name) {
  }

  ~TestSuite() {
  }

private:
  std::string name_;
};

تعديل : في إذا كان هذا هو الدعوة إلى malloc () التي كنت ترغب في تجنب هل يمكن أن تفعل هذا:

class TestSuite {
public:
  TestSuite(const char *name){
    memcpy(name_, name, min(16, strlen(name));
  }

private:
  char name_[16];
};

وهذا سوف يضيع بعض الذاكرة ولكن الذي يمكن أن يكون مسألة على منصات المضمنة.

هل لديك عضوا char name[XYZ] من TestSuite الخاص بك (مع XYZ كبيرة بما يكفي لعرض مريح الاسم) واستخدام strncpy لنسخ سلسلة (مع الحد الأقصى لطول XYZ-1).

وماذا الذي تستخدمه شار * وmalloc عندما يكون لديك لطيفة C ++ الدرجة سلسلة التي يمكن أن تأخذ سلسلة حرفية أو شار * في منشئ لها؟

هل أنت قادرة على استخدام الأمراض المنقولة جنسيا :: سلسلة؟ هل يمكن أن يكون ذلك كما std::string name_ ولها STL يحرص على تخصيص الذاكرة بالنسبة لك ..

class TestSuite {
    public:
      TestSuite(const char* name) : name_(name) {}

      ~TestSuite() {}

    private:
      std::string name_;
};

لا تنس أن تشمل <string>.

المرجعي

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