سؤال

لدي برنامج قديم يتم فيه استخدام بعض وظائف المكتبة وليس لدي تلك المكتبة.

لذلك أنا أكتب هذا البرنامج باستخدام مكتبات C++.يوجد في هذا الكود القديم بعض الوظائف التي تسمى بهذا الشكل

*string = newstrdup("يتم وضع بعض السلاسل هنا");

تم الإعلان عن متغير السلسلة كـ char **string;

ما الذي قد يفعله في تلك الوظيفة المسماة "newstrdup"؟لقد جربت أشياء كثيرة ولكن لا أعرف ماذا يفعل ...هل أستطيع مساعدتك

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

المحلول

ويجب أن يكون هناك سبب أن كتبوا نسخة "الجديد" من strdup. لذلك يجب أن تكون هناك حالة زاوية أنه يعالج بطريقة مختلفة. مثل ربما سلسلة فارغة بإرجاع سلسلة فارغة.

والجواب litb هي بديل ل strdup ، ولكن أعتقد أن هناك السبب أنهم فعلوا ما فعلوا.

إذا كنت تريد استخدام strdup مباشرة، واستخدام تعريف لتسميته، بدلا من كتابة التعليمات البرمجية الجديدة.

نصائح أخرى

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

أعتقد أنه يمكنك التوصل إلى شيء مثل هذا، لأنه يسمى جديدcom.strdup:

char * newstrdup(char const* str) {
    char *c = new char[std::strlen(str) + 1];
    std::strcpy(c, str);
    return c;
}

من المفترض أن تحرره بمجرد الانتهاء من استخدام السلسلة

delete[] *string;

هناك طريقة بديلة للكتابة وهي استخدام malloc.إذا كانت المكتبة قديمة، فمن المحتمل أنها استخدمت ذلك الذي ورثته لغة C++ من لغة C:

char * newstrdup(char const* str) {
    char *c = (char*) malloc(std::strlen(str) + 1);
    if(c != NULL) {
        std::strcpy(c, str);
    }
    return c;
}

الآن، من المفترض أن تقوم بتحرير السلسلة باستخدام free عند الانتهاء:

free(*string);

تفضل الإصدار الأول إذا كنت تكتب باستخدام C++.ولكن إذا كان الكود الموجود يستخدم free لإلغاء تخصيص الذاكرة مرة أخرى، استخدم الإصدار الثاني.احذر أن يعود الإصدار الثاني NULL إذا لم تكن هناك ذاكرة متاحة لخداع السلسلة، في حين أن الأول يطرح استثناءً في هذه الحالة.يجب أخذ ملاحظة أخرى حول السلوك عند اجتياز أ NULL حجة لك newstrdup.اعتمادًا على مكتبتك التي قد تكون مسموحة أو غير مسموح بها.لذا، أدخل الاختبارات المناسبة في الوظائف المذكورة أعلاه إذا لزم الأمر.هناك وظيفة تسمى strdup متوفر في أنظمة POSIX، لكن هذا لا يسمح بأي منهما NULL الحجج ولا يستخدم C++ عامل جديد لتخصيص الذاكرة.

على أي حال، لقد بحثت مع جوجل كود البحث عن newstrdup وظائف وجدت عدد غير قليل.ربما تكون مكتبتك من بين النتائج:

جوجل كود سيرش، نيوستردوب

وو*string = newstrdup("Some string goes here"); خط لا يظهر أي غرابة في newstrdup. إذا string ديه اكتب char ** ثم newstrdup هو مجرد char * يعود كما هو متوقع. يفترض string تم تعيين بالفعل للإشارة إلى متغير نوع char * التي والنتيجة هي أن توضع. وإلا رمز والكتابة من خلال مؤشر غير مهيأ ..

وnewstrdup وربما جعل سلسلة جديدة هي نسخة مكررة من السلسلة التي تم تمريرها. فإنها ترجع مؤشر إلى سلسلة (الذي هو في حد ذاته pointier على الحروف).

ويبدو انه كتب وظيفة strdup () لتعمل على مؤشر الحالية، وربما لإعادة تحيله إلى حجم جديد ومن ثم ملء محتوياته. على الأرجح، وقال انه يفعل ذلك لإعادة استخدام نفس المؤشر في حلقة حيث * سلسلة سيتغير كثيرا في حين منع تسرب على كل استدعاء لاحقة strdup ().

وربما كنت تنفيذ ذلك مثل سلسلة = redup (& سلسلة "محتويات جديدة") .. ولكن هذا مجرد لي.

تعديل : في

إليك قصاصة من بلدي وظيفة "redup" التي يمكن أن تفعل شيئا على غرار ما قمت بنشرها، فقط بطريقة مختلفة:

int redup(char **s1, const char *s2)
{
    size_t len, size;

    if (s2 == NULL)
        return -1;

    len = strlen(s2);
    size = len + 1;

    *s1 = realloc(*s1, size);

    if (*s1 == NULL)
        return -1;

    memset(*s1, 0, size);
    memcpy(*s1, s2, len);

    return len;
}

وبطبيعة الحال، أنا ربما يجب حفظ نسخة من * s1 وواستعادتها في حالة فشل realloc ()، ولكن لم أكن في حاجة للحصول على هذا بجنون العظمة.

أعتقد أنك بحاجة إلى إلقاء نظرة على ما يحدث مع متغير "السلسلة" داخل الكود حيث يبدو النموذج الأولي لوظيفة newstrdup() مطابقًا لإصدار المكتبة strdup().

هل هناك أي مكالمات مجانية (*سلسلة) في الكود؟

قد يبدو الأمر غريبًا، إلا إذا كان يحتفظ داخليًا بنسخة من السلسلة المكررة ويعيد المؤشر إلى نفس السلسلة مرة أخرى.

مرة أخرى، أود أن أسأل لماذا؟

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