كيف يمكنني العثور على الحجم الحقيقي لفئة C ++ الخاصة بي؟

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

  •  18-09-2019
  •  | 
  •  

سؤال

أنا أعمل على مهمة الواجبات المنزلية التي طلب منها استخدام صفائف Char بدلا من السلاسل وقاصة QSort / BSearch. في مكالمتي إلى BSearch أدناه، أنا أعرف أقوم بتمرير حجم الخاطئ للدخول، لكنني لست متأكدا من كيفية الحصول على الحجم الحقيقي، وبالتالي فهو دالة قصاربي لا تجد الكائنات الصحيحة.

هل يمكن لأي شخص أن يساعدني في فهم ما أفتقده؟

#include  <iostream>

using  namespace  std;


typedef Entry*  EntryPtr;
class  Dictionary
{
    public  :
        Dictionary( const char  *filename );
        ~Dictionary();
        const char  *lookupDefinition( const char  *word );

    private  :
        int m_numEntries;
        EntryPtr *m_entries;
        static int compareEntries(const void *leftSide, const void *rightSide);
};

int Dictionary::compareEntries(const void *leftSide, const void *rightSide)
{
    EntryPtr lside = (EntryPtr) leftSide;
    EntryPtr rside = (EntryPtr) rightSide;

    return strcmp(lside->Word, rside->Word);
}

const char *Dictionary::lookupDefinition(const char *word)
{
    if (m_numEntries == 0)
        return 0;

    EntryPtr result = (EntryPtr) bsearch(word, m_entries, 
        m_numEntries, sizeof(m_entries[0]), Dictionary::compareEntries);

    return result->Definition;
}

class Entry
{
        public:
                Entry(const char *line);
                char *Word;
                char *Definition;
};

int  main()
{
    Dictionary  dict( "C:\\path\\file.txt" );
    dict.lookupDefinition("chair");
    return  0;
}
هل كانت مفيدة؟

المحلول

لماذا لا sizeof(Entry) الشغل؟

تغير مرة أخرى - أعتقد أن الحجم يجب أن يكون حجم المؤشر ....

EntryPtr tmp = new Entry("");
tmp->Word = word;

EntryPtr result = (EntryPtr) bsearch(tmp, m_entries, 
        m_numEntries, sizeof(EntryPtr), Dictionary::compareEntries);

نصائح أخرى

المشكلة هي أن وظيفة المقارنة المستخدمة في bsearch تتوقع word أن تكون من النوع Entry* (أو m_entries أن تكون من النوع char**).

أنت تعرف ذلك bsearch يتطلب المدخلات مرتبة، أليس كذلك؟

sizeof(m_entries[0]) يبدو غرامة تماما بالنسبة لي.

تحرير: الآن أرى المشكلة. تحتوي طبقة القاموس الخاصة بك على مجموعة من المؤشرات. المشكلة في وظيفة GrassrentRies، حيث يلقي مؤشرات مرت EntryPtr; ؛ تحتاج إلى إلقاء لهم EntryPtr * في حين أن.

تحرير 2: كما هو مذكور من قبل اميت كومار, ، أنت أيضا تحتاج إلى تغيير المعلمة الرئيسية التي ترسلها إلى BSearch، أو عليك أن تدرك أن المؤشرات التي تتلقاها في حظائر مشاركتها لا تشير إلى نفس الأنواع وستحتاج إلى اثنين من اليائية المختلفة.

سيعمل Sizeof (الدخول). في الغالب يجب استخدام Sizeof من النوع بدلا من مثيل.

Sizeof (الدخول)

الأفضل من الأفضل

الدخول ه؛
Sizeof (ه)؛

أو

الدخول * ه؛
Sizeof (* ه)؛

كل إعطاء نفس النتيجة.

#include "stdio.h"
class Entry {
  double e;
  int i;
};
int main() {
  Entry e;
  printf("%d\n", sizeof(e));
  printf("%d\n", sizeof(Entry));
  printf("%d\n", sizeof(*(&e)));
  return 0;
}

إقرأ ال كتيب بحرص.

ملخص للنقاط التي أدلى بها آخرون، بالإضافة إلى إصدارات المزيد من القضايا:

  • استخدامك حجم صحيح.

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

  • المصابيح في وظيفة المقارنة غير صحيحة. تتلقى وظيفة المقارنة مؤشرا إلى العنصر (والتي في حالتك هي مؤشر الدخول، وبالتالي تستقبل وظيفة المقارنة مؤشرات للمؤشرات إلى الدخول).

  • لقد ألقيت النتيجة إلى النوع الخطأ. مرة أخرى تقوم الوظيفة بإرجاع مؤشر إلى عنصر في الصفيف (المؤشر إلى المؤشر إلى الدخول).

  • أنت لا تحقق مما إذا كانت النتيجة خالية، في حالة عدم وجود المفتاح هناك.

  • ربما يمكنك التخلي عن مستوى واحد من غير مباشر (هل تحتاج حقا إلى مجموعة من المؤشرات بدلا من صفيف من الإدخالات؟)

  • يجب أن تأخذ ذلك كمثال جيد على ما يعنيه الناس عندما يتحدثون عن فضائل السلامة من النوع: في الكود تقريبا يتم خلط جميع الأنواع وأنت تقوم بعمل أشياء خاطئة مع أنواع خاطئة، ومع ذلك لا شكوى واحدة من مترجم. هذا ما تحصل عليه إذا كنت تعاني من void*, ، ما لم تكن تعرف بالضبط ما تفعله.

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

#include <cstdlib>
#include <string>
#include <iostream>

int compare_string(const void* a, const void* b)
{
    return ((const std::string*)a)->compare(**(const std::string**)b);
}

int main()
{
    std::string a("a"), b("b"), c("c");
    std::string* array[3] = { &a, &b, &c };
    std::string key = "b";
    std::string** result = (std::string**)bsearch(&key, array, 3, sizeof(std::string*), compare_string);
    if (result) std::cout << **result << '\n';
}

IMO، سيستغرق وقتا أقل من الوقت لتنفيذ BSearch من النوع الخاص بك من النوع الخاص بك، مما يتطلبه الأمر لمعرفة كل هذا ويختبره وتصحيحه.

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