נושאים פעיליםנושאים פעילים  הצגת רשימה של חברי הפורוםרשימת משתמשים  חיפוש בפורוםחיפוש  עזרהעזרה
  הרשמההרשמה  התחברותהתחברות RSS עדכונים
תיכנות
RSS UnderWarrior Forums : RSS תיכנות
נושא

נושא: Smart pointers

שליחת תגובהשליחת נושא חדש
כותב
הודעה << נושא קודם | נושא הבא >>
דניאל ל.
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 19 August 2006 בשעה 12:45 | IP רשוּם
ציטוט דניאל ל.

הורדתי את המדריך הקצר שמפורסם פה באתר על smart pointers, ונתקלתי בקטע קוד שאני מתלבט אם הוא בעייתי או שאולי אני טועה.
להלן קטע הקוד:
קוד:

#include <iostream>
#include <memory>
using namespace std;
int main()
{
auto_ptr<int> p;
int i = 7;
p.reset(&i);
cout << "The pointer points to: " << *p << endl;
*p = 10;
cout << "Contents of i: " << i << endl;
return 0;
}

אולי לא הבנתי נכון אבל לפי מה שמוסבר שם בסוף הפונקציה בקריאה ל-destructor של p תהיה קריאה ל-delete עם הכתובת של i, ו- i לא הוקצה ע"י new (שזה אמור להיות בעייתי עד כמה שידוע לי).
חזרה לתחילת העמוד הצג את כרטיס החבר של דניאל ל. חפש הודעות אחרות של דניאל ל. בקר בדף הבית של דניאל ל.
 
ReX :D
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 19 August 2006 בשעה 17:07 | IP רשוּם
ציטוט ReX :D

הכוונה היא שתיהיה קריאה לdestructor והזיכרון
של המצביע p ישוחרר.
חזרה לתחילת העמוד הצג את כרטיס החבר של ReX :D חפש הודעות אחרות של ReX :D בקר בדף הבית של ReX :D
 
דניאל ל.
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 19 August 2006 בשעה 20:36 | IP רשוּם
ציטוט דניאל ל.

אבל ה-Destructor של auto_ptr עושה delete למצביע שהוא מכיל...
חזרה לתחילת העמוד הצג את כרטיס החבר של דניאל ל. חפש הודעות אחרות של דניאל ל. בקר בדף הבית של דניאל ל.
 
אורח
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 19 August 2006 בשעה 20:47 | IP רשוּם
ציטוט אורח

נו בסדר הוא מוחק את p ולא את i.
חזרה לתחילת העמוד הצג את כרטיס החבר של אורח חפש הודעות אחרות של אורח בקר בדף הבית של אורח
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 20 August 2006 בשעה 02:21 | IP רשוּם
ציטוט אלצ'קו

על פניו נראה שאתה צודק.



ReX :D כתב:
הכוונה היא שתיהיה קריאה לdestructor והזיכרון
של המצביע p ישוחרר.

כן. והמפרק של ה-auto_ptr ינסה לעשות delete למצביע שהוא שומר אצלו. אלא שהמצביע הוא למשתנה שנמצא במחסנית ולא על הערימה. נחש למה זה אמור לגרום...
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
aassaa1
משתמש מתחיל
משתמש מתחיל


הצטרף / הצטרפה: 24 August 2006
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 24 August 2006 בשעה 15:54 | IP רשוּם
ציטוט aassaa1

אם כתבו את הSMART POINERS כמו שצריך זה לא ימחק משהו שלא הוקצה

 

חזרה לתחילת העמוד הצג את כרטיס החבר של aassaa1 חפש הודעות אחרות של aassaa1
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 24 August 2006 בשעה 22:10 | IP רשוּם
ציטוט אלצ'קו

aassaa1 כתב:
אם כתבו את הSMART POINERS כמו שצריך זה לא ימחק משהו שלא הוקצה


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

קרא את זה. אולי תלמד משהו.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
aassaa1
משתמש מתחיל
משתמש מתחיל


הצטרף / הצטרפה: 24 August 2006
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 25 August 2006 בשעה 18:01 | IP רשוּם
ציטוט aassaa1

template<class T> auto_ptr {

T* ptr

//...

bool DidNew

//...

auto_ptr::~auto_ptr(){

if (DidNew) delete[] ptr

 

}

חזרה לתחילת העמוד הצג את כרטיס החבר של aassaa1 חפש הודעות אחרות של aassaa1
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 25 August 2006 בשעה 18:20 | IP רשוּם
ציטוט אלצ'קו

חכם בלילה, אה?

ואיך יקבע ערכו של DidNew? ומה פתאום החלטת שמשתמשים ב-delete[]‎ ולא ב-delete? אחלה קוד, שברגע שאשתמש בו במקום במימוש ש-MS מביאים לי, לאחר קימפול מחדש, כל הקודים שלי יפסיקו לפעול, כי ה-auto_ptr הגאוני שלך מנסה לעשות delete[]‎ למה שהושג בעזרת new...
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
אורח
אורח
אורח


הצטרף / הצטרפה: 01 October 2003
משתמש: אונליין
הודעות: 12647
נשלח בתאריך: 27 August 2006 בשעה 05:43 | IP רשוּם
ציטוט אורח

אלצ'קו כתב:
על פניו נראה שאתה צודק.



ReX :D כתב:
הכוונה היא שתיהיה קריאה לdestructor והזיכרון
של המצביע p ישוחרר.

כן. והמפרק של ה-auto_ptr ינסה לעשות delete למצביע שהוא שומר אצלו. אלא שהמצביע הוא למשתנה שנמצא במחסנית ולא על הערימה. נחש למה זה אמור לגרום...

למה זה יגרום?
וזה באמת מנסה למחוק את ה i? אם כן, אז ה smart pointers לא ממש חכמים :
חזרה לתחילת העמוד הצג את כרטיס החבר של אורח חפש הודעות אחרות של אורח בקר בדף הבית של אורח
 
aassaa1
משתמש מתחיל
משתמש מתחיל


הצטרף / הצטרפה: 24 August 2006
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 27 August 2006 בשעה 10:19 | IP רשוּם
ציטוט aassaa1

אלצ'קו כתב:
חכם בלילה, אה?

ואיך יקבע ערכו של DidNew? ומה פתאום החלטת שמשתמשים ב-delete[]‎ ולא ב-delete? אחלה קוד, שברגע שאשתמש בו במקום במימוש ש-MS מביאים לי, לאחר קימפול מחדש, כל הקודים שלי יפסיקו לפעול, כי ה-auto_ptr הגאוני שלך מנסה לעשות delete[]‎ למה שהושג בעזרת new...

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

bool isArray

לשאלה הראשונה אפשר להעמיס את האופרטור new כך שיקבע את ערכו של DidNew 

קוד:

template <class T>

void *operator new(size_t size);

ואת האופרטור new[] כך שיקבע גם את ערכו של isArray

חזרה לתחילת העמוד הצג את כרטיס החבר של aassaa1 חפש הודעות אחרות של aassaa1
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 27 August 2006 בשעה 11:11 | IP רשוּם
ציטוט אלצ'קו

אורח כתב:
למה זה יגרום?
וזה באמת מנסה למחוק את ה i? אם כן, אז ה smart pointers לא ממש חכמים :


זה באמת באמת ינסה למחוק את ה-i. למה שלא ינסה? בקוד של auto_ptr בודקים האם יש לו ownership על המצביע, ואם כן הוא מבצע עליו delete במפרק, או בהעברת בעלות, או אם "מחברים" אליו מצביע חדש.

למה זה יגרום? התוצאות של שימוש ב-delete על מצביע שלא הושג באמצעות new אינן מוגדרות. זה אומר שהפעולה הזו יכולה לעשות כל דבר, בין קריסה מיידית, קריסה בעתיד ברגע לא קשור, או הפקה של תוצאות בלתי-צפויות. בעצם, המשמעות של "תוצאה בלתי מוגדרת" היא שהדבר היחיד שכנראה לא יקרה, הוא מה שאתה מצפה שיקרה. כל השאר, כולל הכחדה של כל פרות משה רבנו בעולם,הוא אפשרות.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 27 August 2006 בשעה 11:14 | IP רשוּם
ציטוט אלצ'קו

aassaa1 כתב:

אלצ'קו כתב:
חכם בלילה, אה?

ואיך יקבע ערכו של DidNew? ומה פתאום החלטת שמשתמשים ב-delete[]‎ ולא ב-delete? אחלה קוד, שברגע שאשתמש בו במקום במימוש ש-MS מביאים לי, לאחר קימפול מחדש, כל הקודים שלי יפסיקו לפעול, כי ה-auto_ptr הגאוני שלך מנסה לעשות delete[]‎ למה שהושג בעזרת new...

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

bool isArray

לשאלה הראשונה אפשר להעמיס את האופרטור new כך שיקבע את ערכו של DidNew 

קוד:

template <class T>

void *operator new(size_t size);

ואת האופרטור new[] כך שיקבע גם את ערכו של isArray



אתה פשוט מביך את עצמך. זה שאתה "בטוח שיש דרך לעשות את זה" לא אומר שהיא קיימת. בעצם, ידוע שהיא לא קיימת. זה פשוט בלתי-אפשרי ללא שינוי הממשק של auto_ptr.

זה נחמד שיש לך bool isArray, אבל אין לך דרך לקבוע את הערך שלו, בדיוק כמו שאין לך דרך לקבוע את הערך של DidNew. הניסיון החביב שלך לפתור את זה ע"י העמסת new הוא way of course. הרי auto_ptr בכלל לא משתמש ב-new, ואובייקטים מטיפוס auto_ptr אמורים להיות מוקצים סטטית. ה-new נעשה על הטיפוס שמשתנה שלו ה-auto_ptr מחזיק.

בקיצור, במקום לבלבל את המוח, תן דוגמה למימוש שלם (יעני אחשלי, קוד שאני יכול לקמפל, ויהווה תחליף שלם ל-auto_ptr שיש לי כרגע) שיודע לזהות מערכים ומצביעים שלא הושגו בעזרת new...
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 
aassaa1
משתמש מתחיל
משתמש מתחיל


הצטרף / הצטרפה: 24 August 2006
מדינה: Israel
משתמש: מנותק/ת
הודעות: 6
נשלח בתאריך: 27 August 2006 בשעה 12:21 | IP רשוּם
ציטוט aassaa1

תקרא את המדריך ההוא עוד פעם תראה שכל מה שאמרתה כרגע לא נכון אם תחשוב קצת תראה שהמימוש שלו ממש קל
חזרה לתחילת העמוד הצג את כרטיס החבר של aassaa1 חפש הודעות אחרות של aassaa1
 
אלצ'קו
אחראי פורומים
אחראי פורומים
סמל אישי
ג2ר פ33תי

הצטרף / הצטרפה: 20 January 2006
משתמש: מנותק/ת
הודעות: 609
נשלח בתאריך: 27 August 2006 בשעה 12:59 | IP רשוּם
ציטוט אלצ'קו

לסיכום, לא הבנת מילה ממה שהרב כתב, וטענת פעם אחר פעם 3 שטויות ענקיות:
  • auto_ptr לא ינסה לעשות delete למצביע שלא נוצר בעזרת new. (הוא ינסה ועוד איך)
  • יש דרך ב-CPP תקני לגלות האם הזיכרון שאליו מצביע מצביע הוקצה סטטית או בעזרת new. (בלתי אפשרי, שלא להזכיר את זה שאת m/calloc שכחת)
  • יש דרך לגלות האם מצביע הושגה באמצעות new או באמצעות new[]‎ (כנ"ל. בלתי אפשרי לחלוטין)
והכי טוב: כתבת שהמימוש של שלושת הדברים הבלתי אפשריים האלה הוא "ממש קל".

ועכשיו סיכום עבורך: שמור את השטויות האלה לעצמך. אתה לא מסוגל להודות בטעות, לא נורא. בעיה שלך. אל תחלק לאנשים "טיפים" שגויים.
חזרה לתחילת העמוד הצג את כרטיס החבר של אלצ'קו חפש הודעות אחרות של אלצ'קו
 

אם ברצונך להגיב לנושא זה עליך קודם להתחבר
אם אינך רשום/ה כבר עליך להרשם

  שליחת תגובהשליחת נושא חדש
גרסת הדפסה גרסת הדפסה

קפיצה לפורום
אינך יכול/ה לשלוח נושאים חדשים בפורום זה
אינך יכול/ה להגיב לנושאים בפורום זה
אינך יכול/ה למחוק את הודעותיך ותגוביך בפורום זה
אינך יכול/ה לערוך את הודעותיך ותגובותיך בפורום זה
אינך יכול/ה לצור סקרים בפורום זה
אינך יכול/ה להצביע בסקרים בפורום זה