עבור לתוכן

שאלה ב C++

Featured Replies

פורסם

שלום,

אני מנסה להתשמש ב HASH MAP של STL ומקבל את השגיאה הבאה בעת קומפילציה: C2668

לפי מה שאני מבין אני אמור לממש איזהשהו פרדיקט השוואתי של האיברים שאני מחזיק ב HASH (אובייקטים משלי ולא טיפוסים בסיסיים)

מה שכן אני לא מבין בדיוק איזה פרדיקטים אני אמור לממש חיפוש בגוגל וב MSDN לא הניב הרבה תוצאות..

אשמח לעזרה ממיש יצא לו לגעת בזה (דוגמא תתקבל אפילו עוד יותר בברכה)

מקס.

פורסם
  • מחבר

תודה רבה!

אני מניח שבתור פונקציית ה HASH אני יכול להשתמש פשוט ב- hash_map::hasher היות ואני חייב לציין שם משהו

אם אני מגדיר פרדיקט השוואתי... או שמה אני לא מבין נכון וגם את פונקציית ה HASH אני צריך לממש בשביל שהעסק יעבוד טוב?

(נראה לי לא סביר כי מה אכפת לפונק' שלהם בכלל מה היא מקודדת כל עוד זה לא שווה אבל עדיף דעה שנייה)

  • 3 שבועות מאוחר יותר...
פורסם
  • מחבר

אם זה אחד מהטיפוסים ברשימה בעמוד הזה, אתה יכול להשתמש במכיל הזה:

http://www.sgi.com/tech/stl/hash.html

יש מצב שהפונקציית HASH הבסיסית שלהם דפוקה?

כלומר הנחתי שאם אני מכניס מחרוזות היא יודעת לקודד אותן כמו שצריך וראיתי שנופלות לי 2 מחרוזות שונות לאותו התא...

הגיוני שדבר כזה יקרה? (לא מדובר על מחרוזות ארוכות כ 10-11 תווים..) הייתי מצפה שהפונק' HASH תהיה יותר אמינה מזה..

מה שעשיתי הגדרת HASH שהמפתח הוא CHAR * והאיברים הם וקטורים וראיתי שאני מגיע למצב שבאחד הוקטורים יש לי דברים

כבר למרות שאני מכניס מידע בפעם הראשונה - ואז שמתי לב שזה בכלל נופל על וקטור של תא אחר (בתוך הוקטורים אני מחזיק טיפוסים

שבין היתר יודעים לומר לי את הדברים האלה )

יש סיכוי שזה דריכת זכרון שלי? (נראה לי לא סביר כל כך...) או שבאמת יתכן שה HASH שלהם דפוק קצת מנסיונכם וכדאי לחפש פונקציית

קידוד אחרת...? :s07:

פורסם

בעקרון אתה יכול להגדיל את ה-Bucket count (ב-Constructor או ב-resize)

אבל זה לא אמור לקרות. ה-char*‎ שלך הם Null terminated?

פורסם

צריך לבדוק אם הפונצית hash שלהם עובדת על חתיכות זיכרות (איך שהיא אמורה לעבוד) או על ערכים. בכל מקרה אם השתמשת ב char * צריך להזהר שהפונקצית hash לא משתמשת בערך של המצביע (pointer ) אלא במה שהוא מצביע אליו כי אם הפונקצית hash נראת ככה :



for(i=0;i<sizeof(T);++i)
j=hash(j,((char* obj))[i]);



זה אומר שאתה בבעיה בגלל שהוא מתיחס לT ולא מה שT מצביע אליו כסוג .

פורסם

במקרה הזה המימוש של פונקציית ה-hash הוא של SGI בעצמם, וכנראה משותף לכל הקומפיילרים -

http://www.sgi.com/tech/stl/stl_hash_fun.h

inline size_t __stl_hash_string(const char* __s)
{
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5*__h + *__s;

return size_t(__h);
}

__STL_TEMPLATE_NULL struct hash<char*>
{
size_t operator()(const char* __s) const { return __stl_hash_string(__s); }
};

__STL_TEMPLATE_NULL struct hash<const char*>
{
size_t operator()(const char* __s) const { return __stl_hash_string(__s); }
};

פורסם
  • מחבר

בעקרון אתה יכול להגדיל את ה-Bucket count (ב-Constructor או ב-resize)

אבל זה לא אמור לקרות. ה-char*‎ שלך הם Null terminated?

ה HASH אצלי מכיל סה"כ כמה מאות-אלפי רשומות מבחינתו. זה שכל רשומה הינה וקטור זה משהו אחר... במצב של כמה אלפים

המספר דליים הבסיסי שלו אמור לעבוד בצורה סבירה בעצמו אני מניח לא?

יש לך הערכה לכמה דליים אני זקוק נגיד עבור 5000 רשומות...? (אני נתקלתי בבעיה כבר בערך ב 100 רשומות בבדיקה שעשיתי..)

לגבי NULL TERMINATED אני מניח שכן אני מוציא את המחרוזות מ CSTRING ויוצא מנקודת הנחה שהוא מחזיר דברים שהם NULL TERMINATED

ככה אני מכניס מפתחות:

(MyHash[MyString->GetName().GetBuffer(0)]).push_back(MyString);			

וככה אני בודק ב IF אם מפתח קיים או לא קיים:

MyHash.find(MyString.GetBuffer(0)) != MyHash.end()

אם אני נכנס פנימה אני מסתכל ובודק את המחרוזות של MYSTRING ומה שיש ב HASH תכלס איפה שהוא מצא את המפוע לטענתו:

((*(MyHash.find(MyString.GetBuffer(0)))).second).begin()

[br]פורסם בתאריך: 5.04.2007 בשעה 11:50:23


צריך לבדוק אם הפונצית hash שלהם עובדת על חתיכות זיכרות (איך שהיא אמורה לעבוד) או על ערכים. בכל מקרה אם השתמשת ב char * צריך להזהר שהפונקצית hash לא משתמשת בערך של המצביע (pointer ) אלא במה שהוא מצביע אליו כי אם הפונקצית hash נראת ככה :



for(i=0;i<sizeof(T);++i)
j=hash(j,((char* obj))[i]);



זה אומר שאתה בבעיה בגלל שהוא מתיחס לT ולא מה שT מצביע אליו כסוג .

מצטער לא נראה לי שהבנתי... אני יוצא מנקדות הנחה שהוא מסתכל על CHAR * כעל מה שאני מצביע עליו ולא כעל הכתובת שאני מצביע אליה - אבל גם

אם כן לא אמור לקרות מזה שום נזק היות וכל האיברים שאני מכניס אמורים להיות איברים חדשים (אובייקטים חדשים שאני יוצר.. ולכן אני חושב שגם הזכרון

ל CSTRINGים שלהם מוקצה כל פעם מחדש, הלא כן?)[br]פורסם בתאריך: 5.04.2007 בשעה 11:56:51


טוב אכן נראה שהבעיה הייתה באופן הגישה שלי ל CSTRING... מסתבר שזה לא בריא לגשת למידע בו דרך GETBUFFER..

במקום זה מה שעשיתי קאסטינג כפול (char *)(LPCSTR)

וזה עובד...

תודה לכל המגיבים! :yelclap:

פורסם

טעות, למחוק

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים