פורסם 2007 ביוני 918 שנים שלוםאני משתמש ב Turbo Pascal 7.בתוכנית שבניתי המשתמשת בפוינטרים יצרתי תאים בזיכרון בשימוש בפקודה newאם למשל יש לי פוינטר pאז השתמשתי ב new(p).בקטע מסוים בתוכנית אני צריך למחוק תאים מסוימים שיצרתי, כלומר שערכם יהיה שווה nil.השתמשתי בפקודה dispose כךdispose(p).כאשר p מצביע על התא שאני רוצה למחוק.הקומפיילר מראה שהכל תקין ואני יכול להפעיל את התוכנית אבל ברגע שהתוכנית מגיעה לשימוש בdispose אני מקבל הודעת שגיאה::error 204 invalid pointer operationתודה לעוזרים
פורסם 2007 ביוני 918 שנים מחבר קוד התכנית:program treebuild;type tree_type = char {integer ...}; tree_pointer = ^node; node = record data: tree_type; left, right, parent: tree_pointer end; bin_tree = tree_pointer; node_position = tree_pointer;procedure create_tree (var t: bin_tree); begin t := nil; end;function left_child (n: node_position): node_position; begin left_child := n^.left; end;function right_child (n: node_position): node_position; begin right_child := n^.right; end;function parent (n: node_position): node_position; begin parent := n^.parent; end;function key (n: node_position): tree_type; begin key := n^.data; end;function root (t: bin_tree): node_position; begin root := t; end;function tree_is_empty (t: bin_tree): boolean; begin tree_is_empty := t = nil; end;procedure tree_insert (k: tree_type; var t:bin_tree; var pn: node_position); begin if t=nil then begin new (t); t^.data := k; t^.left :=nil; t^.right := nil; t^.parent := pn; end else if k < key (t) then tree_insert(k,t^.left,t) else tree_insert(k,t^.right,t); end; {tree_insert}procedure build_tree (var tree:bin_tree);var k:char; pn:node_position;begin pn:=nil; create_tree(tree); writeln('Enter values for the tree. After each value use "Enter". Finish with a "." as a value'); readln(k); while (k<>'.') do begin tree_insert(k,tree,pn); readln(k); end;end;procedure visit (n: node_position); begin write (' ', key(n), ' '); end;procedure inorder (t: bin_tree); begin if not tree_is_empty (t) then begin inorder (left_child (t)); visit (t); inorder (right_child (t)); end; end;procedure inorder2 (t: bin_tree);var n,n2:node_position; begin while (t<>nil) do begin if (left_child(t)<>nil) then begin t:=left_child(t); end else begin visit(t); if (right_child(t)<>nil) then t:=right_child(t) else begin n:=t; t:=parent(t); dispose(n); end; end; end; end;var tree:bin_tree;beginbuild_tree(tree);inorder(tree);writeln;inorder2(tree);readln;end.
פורסם 2007 ביוני 918 שנים שכחת לבדוק אם new(t) הצליח. העובדה שאתה יכול לכתוב ולקרוא מידע לא מוכיחה כלום.גם אם זה לא הבאג במקרה הזה, כשאתה מקצה זכרון תמיד (אבל תמיד!) תבדוק אם ההקצאה הצליחה.כנ"ל ברוב (עדיף בכל) קריאות מערכת הפעלה, כגון פתיחת קובץ.הבעיה שלך היא מימושית ואלגוריתמית.תסתכל על האיטרציה לאחר הראשונה שביצעת t = parent(t). במקרה זה באיטרציה הבאה הילדים של ההורה עדיין מאותחלים למצביעים שאינם נכונים כבר כי שחררת אותם.עקרונית אחרי שאתה משחרר יחד אתה צריך לעדכן באב שלו את המצביע ל-nil. במימוש שלך אתה צריך להוסיף אחרי ה-dispose משהו כמו n^.xxx:= nil אבל אתה לא יכול כי אתה לא יודע אם XXX הוא left או right במימוש שלך.הפתרון? תשנה מעט את האלגוריתם כך שתמיד תשחרר את הבן הימני או השמאלי דרך האבא. רמז: תכתוב את הפונקציה הפשוטה is_leaf(t) שתעזור לך.נכון שמצביעים זה כיף?
ארכיון
דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.