Từ 1 tới 10 trên tổng số 10 kết quả

Đề tài: Câu hỏi nhỏ về con trỏ, mọi người vào giúp cái nào .

  1. #1
    Ngày gia nhập
    03 2008
    Nơi ở
    Đà Nẵng city
    Bài viết
    40

    Exclamation Câu hỏi nhỏ về con trỏ, mọi người vào giúp cái nào .

    Tình hình là đã tìm trong các câu hỏi thường gặp trong box, nhưng vẫn chưa tìm được cái muốn hỏi, đó là lý do chình mình lập 1 topic mới hờ hờ


    Có 1 đoạn code nhỏ sau :
    Hàm khởi tạo sao chép nằm trong lớp node.
    C++ Code:
    1. class node      //lớp node sau này tớ hay dùng để khai báo con trỏ kiểu node
    2. {
    3.         char name;
    4.         node *next;
    5.     public:
    6.         node( const char & );
    7.         node( const node & );
    8.           .................
    9. }
    C++ Code:
    1. node::node( const node &_node )
    2. {
    3.             name = _node.name;     //name là kiểu char, chứa 1 ký tự
    4.             next = _node.next;
    5. }

    Vậy nếu mình khai báo như sau :
    C++ Code:
    1. node *head = new node;
    2. head->name='a';
    3. head->next= ......
    4. node *temp = new node( head ); // như thế này thì head cũng là 1 con trỏ node
    Ở đây thuộc tính next của temp( temp->next ) được nhận địa chỉ cùng 1 vùng nhớ giống thuộc tính next của head ( head->next ).
    Và mình có lệnh sau :
    C++ Code:
    1. delete head;
    Như vậy là giải phóng vùng nhớ do head trỏ tới, vậy thì con trỏ temp có còn ko, hay là nó trở thành vô gia cư ?
    Nếu như nó vô gia cư , tức là ko còn trỏ tới đâu nữa, vậy để khắc phục điều này thì mình có thể viết code như sau được không:
    C++ Code:
    1. node::node( const node &_node )
    2. {
    3.             name = _node -> name;
    4.             next = new node;
    5.             next = _node->next;
    6. }
    Và khi đó mình lại có 1 lệnh như sau:
    C++ Code:
    1. node *temp = new node( head );
    Rồi lại delete head :
    C++ Code:
    1. delete head;
    Vậy thì bây giờ temp có còn trỏ nữa ko ?
    Đã được chỉnh sửa lần cuối bởi camping29 : 30-11-2008 lúc 12:49 AM.

  2. #2
    Ngày gia nhập
    11 2008
    Bài viết
    186

    vài nhận xét qua của Kim, còn đúng hay sai thì Kim không rõ đâu nha

    1. Đoạn này:
    C++ Code:
    1. node::node( const node &_node )
    2. {
    3.             name = _node -> name;     //name là kiểu char, chứa 1 ký tự
    4.             //next = new node;
    5.             next = _node->next;
    6. }

    _node ở đây là tham chiếu chứ hổng phải con trỏ :-??

    2. con trỏ là temp thì phải là delete temp chứ head đâu có làm gì ở đây :-??
    Ước mơ vươn tới Linux Developer.
    Đang trong quá trình tập luyện:
    1. C system programming
    2. GNU distribution
    3. Gtk+/Gnome Application Programming.

    Bác nào giỏi lĩnh vực này giúp Kim với nha. Kim cám ơn nhiều !!!

  3. #3
    Ngày gia nhập
    01 2008
    Nơi ở
    UIT
    Bài viết
    129

    Phần trên đúng như bvKim nói, _node là tham chiếu chứ ko phải con trỏ ! Mà cho dù là con trỏ đi nữa thì tôi thấy nó chẳng ảnh hưởng gì đến temp cả !

  4. #4
    Ngày gia nhập
    03 2008
    Nơi ở
    Đà Nẵng city
    Bài viết
    40

    Tớ đã thêm lớp node vào bài post # 1 rồi, mấy bro quay ngược lên xem lại hộ với, có thể câu hỏi chưa rõ ràng lắm, ý tôi ở đây là, nếu 1 con trỏ a được cấp 1 vùng nhớ xyz, ta lại có con trỏ b được gán bằng a ( b = a, b, a la 2 con trỏ ), khi đó, b và a cùng trỏ đến 1 vùng nhớ, vậy nếu mình giải phóng a, hoặc b, thì cái còn lạibị gì ko ( bị ở đây có thể là khi 1 vùng nhớ nó đang trỏ đc giải phóng thì có ko còn trỏ nữa, có nghĩa là nó bằng NULL rồi. )

    Cảm ơn đã góp ý nha

  5. #5
    Ngày gia nhập
    03 2008
    Nơi ở
    Đà Nẵng city
    Bài viết
    40

    Sorry vì lỗi các đoạn code, mình sửa lại rồi, tại cái này mình cảm thấy hơi khó nói, ai giúp với nha

  6. #6
    Ngày gia nhập
    11 2008
    Nơi ở
    Neverland
    Bài viết
    48

    Mặc định Câu hỏi nhỏ về con trỏ, mọi người vào giúp cái nào .

    Vẫn không hiếu ý cả bạn lắm dựa thao Code trên thì :
    C++ Code:
    1. node *temp = new node( head );
    temp được khai báo và cấp phát vùng nhớ riêng , temp và head là hai biến con trỏ và khi được khai báo chúng ở hai địa chỉ hoàn toàn khác nhau . temp trỏ tới ô nhớ lưu biến kiểu node có giá trị là *temp và head trỏ tới ô nhớ có lưu biến kiểu node có giá trị *head . Chúng chỉ có điểm giống nhau là trường giá trị next bằng nhau và trường next đó cũng là biến con trỏ .
    C++ Code:
    1. head->next= ...... //Thằng ..... cũng là con trỏ cũng như các biến bình thường khác nó có địa chỉ và giá trị ở đâu đó trong bộ nhớ
    Khi ta xóa biến head đi
    C++ Code:
    1. delete head;
    Giải phóng vùng nhớ được cấp phát cho con trỏ head nhưng head và temp là hai biến ở hai vùng nhớ khác nhau --> temp không bị ảnh hưởng gì phép xóa này chỉ làm đứt liên kết head->next chứ cái thằng ....... không ảnh hưởng gì cả và temp->next vẫn trỏ đến cái thằng ....... đó .
    Vì khi tạo biến temp bạn đã làm như sau :
    C++ Code:
    1. node* temp = new node(head); //dùng new --> temp và head sẽ là hai thằng riêng biệt
    Làm cách như thế này :
    C++ Code:
    1. node::node( const node &_node )
    2. {
    3.             name = _node -> name;
    4.             next = new node;
    5.             next = _node->next;
    6. }
    Hình như không có ý nghĩa gì cả . Ý tui là vậy sai hok có chịu trách nhiệm nha .
    I'm superman

  7. #7
    Ngày gia nhập
    11 2008
    Bài viết
    186

    xóa head thì temp chẳng ảnh hưởng gì cả

    temp là con trỏ tới địa chỉ của head; head bị xóa thì tức là nó không còn được allocate trên memory và không còn lưu địa chỉ nó trỏ tới. còn temp thì vẫn trỏ tới cái địa chỉ đó.
    Sau khi xóa head thì :
    temp = địa chỉ nó đang trỏ tới
    *temp = null; vì giá trị bị xóa rồi

    Kim cũng không chắc lắm.

    bạn thử in ra địa chỉ của temp trước và sau khi xóa head xem
    C++ Code:
    1. std::cout << ios::hex << temp;
    Ước mơ vươn tới Linux Developer.
    Đang trong quá trình tập luyện:
    1. C system programming
    2. GNU distribution
    3. Gtk+/Gnome Application Programming.

    Bác nào giỏi lĩnh vực này giúp Kim với nha. Kim cám ơn nhiều !!!

  8. #8
    Ngày gia nhập
    12 2006
    Nơi ở
    US
    Bài viết
    1,917

    - Vấn đề ở đây là con trỏ được cấp phát với new nhất định phải được delete bởi chính con trỏ đó, và trung nói rất chính xác( very good point ), và chắc chắn đây là memory leak.
    temp được khai báo và cấp phát vùng nhớ riêng , temp và head là hai biến con trỏ và khi được khai báo chúng ở hai địa chỉ hoàn toàn khác nhau . temp trỏ tới ô nhớ lưu biến kiểu node có giá trị là *temp và head trỏ tới ô nhớ có lưu biến kiểu node có giá trị *head . Chúng chỉ có điểm giống nhau là trường giá trị next bằng nhau và trường next đó cũng là biến con trỏ .
    - Thứ 2, ý của em camping29( không phải dựa vào code đó ), anh nghĩ anh hiểu ý em, và đó là vấn đề rất thường gặp trong C/C++, dangling pointer -> lỗi nguy hiểm, 2 con trỏ không nên được trỏ chung đến 1 vùng nhớ. Dù cho em có đúng trong việc delete vùng nhớ mà con trỏ( được cấp phát với new tạo ra ) ta không nên tạo ra trường hợp này, nguy hiểm và làm code trở nên phức tạp, handle con trỏ cần phải cẩn thận, vì dù có delete vùng nhớ đó thì con trỏ đó vẫn là 1 "dangling pointer" con trỏ trỏ tới vùng nhớ đã bị delete. Khi em học quá tải toán tử anh bảo đảm sách nào cũng đề cập tới vấn đề này.
    - Thứ 3, Node là 1 class chứ không phải struct, làm sao em gọi thế này được ?
    C++ Code:
    1. node *head = new node;
    2. head->name='a';
    3. [B]head->next= ......[/B]
    4. node *temp = new node( head ); // như thế này thì head cũng là 1 con trỏ node
    - Một điều đáng chú ý là không nên để delete đơn độc nếu có dùng naked pointer( new + delete hay malloc + free ), ý anh là ví dụ em muốn nói rằng ta lấy lại vùng nhớ thì nên tạo 1 hàm với 1 tên thật ý nghĩa nhấn mạnh rằng ta muốn delete lại vùng nhớ. Mặc dù ta phải paid-off cho 1 function call nhưng nó cần thiết để code ta trở thành bug-free. Em càng xài pointer em sẽ càng hiểu tại sao nó khó xài, vì debug với con trỏ không bao giờ dễ dàng thậm chí đối với experienced programmer.
    - Còn lỗi đó là reference thì quá rõ ràng. Các bạn trên cũng đã nêu ra rồi !

  9. #9
    Ngày gia nhập
    03 2008
    Nơi ở
    Đà Nẵng city
    Bài viết
    40

    Tình hình là 2 hôm nay, máy nhà có chút vấn đề nên reply lại hơi chậm, sorry các bro đã giúp đỡ.

    Tóm lại , khi cấp phát dùng từ khóa new thì con trỏ đó được cấp riêng 1 vùng nhớ để lưu nó, còn nó vẫn chỉ đến 1 vùng nhớ cố định, khi xóa nó = delete thì vùng nhớ lưu nó được giải phóng, còn vùng nhớ nó trỏ tới vẫn còn, công việc xóa con trỏ chỉ là de-allocate nó trong memory. Em nói đúng hem , hem đúng thì đính chính sau.

    Còn nếu gán trực tiếp 2 con trỏ , 1 lần đọc rồi nhưng lại ko nhớ ở đâu, hình như trong C++ How to Program, cái nài để về nghiên cứu.
    Đã được chỉnh sửa lần cuối bởi camping29 : 01-12-2008 lúc 04:11 PM.

  10. #10
    Ngày gia nhập
    07 2008
    Nơi ở
    /media/Anime
    Bài viết
    2,288

    Trích dẫn Nguyên bản được gửi bởi camping29 Xem bài viết
    Tình hình là 2 hôm nay, máy nhà có chút vấn đề nên reply lại hơi chậm, sorry các bro đã giúp đỡ.

    Tóm lại , khi cấp phát dùng từ khóa new thì con trỏ đó được cấp riêng 1 vùng nhớ để lưu nó, còn nó vẫn chỉ đến 1 vùng nhớ cố định, khi xóa nó = delete thì vùng nhớ lưu nó được giải phóng, còn vùng nhớ nó trỏ tới vẫn còn, công việc xóa con trỏ chỉ là de-allocate nó trong memory. Em nói đúng hem , hem đúng thì đính chính sau.

    Còn nếu gán trực tiếp 2 con trỏ , 1 lần đọc rồi nhưng lại ko nhớ ở đâu, hình như trong C++ How to Program, cái nài để về nghiên cứu.
    Bạn cần phải hiểu rõ thế này : cấp phát và giải phóng ko có nghĩa là máy sẽ tạo thêm hoặc hủy vùng nhớ ấy đi. Thực tế là những vùng nhớ này luôn tồn tại trong bộ nhớ máy tính. Khi cấp phát thì vùng nhớ đó sẽ được ghi nhận lại là đang được dùng, khi hủy thì vùng nhớ đó lại được ghi nhận là đang rảnh. Khi hủy xong, nếu như vẫn còn có con trỏ nào trỏ tới vùng nhớ đó thì nó vẫn có khả năng truy xuất vùng nhớ như bình thường, tuy nhiên chương trình sẽ bị rối loạn hoạt động, thậm chí bị crash.
    Càng yêu mèo thì mèo càng mập. Mèo càng mập ta lại càng yêu.

Các đề tài tương tự

  1. Sự cố Nhờ mod chuyển giúp bài "Sắp xếp số thứ tự ngay trong bảng của 1 database?" từ MySQL sang MSSQL giúp!
    Gửi bởi hu-xeko trong diễn đàn Ý kiến, đề xuất và khiếu nại
    Trả lời: 1
    Bài viết cuối: 12-03-2012, 07:48 PM
  2. Mới nhập môn khó quá , cần trợ giúp [Vấn đề của bạn cần muốn giúp là gì ?]
    Gửi bởi cuingo212 trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 5
    Bài viết cuối: 22-10-2011, 08:43 AM
  3. Chương trình giúp một học sinh cấp 1 học phép nhân, xử lý hàm rand, giúp mình với?
    Gửi bởi chankx trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 2
    Bài viết cuối: 12-05-2009, 08:52 PM
  4. Code giúp add một key vào registry, ai giúp em?
    Gửi bởi olavien trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 5
    Bài viết cuối: 12-12-2007, 08:45 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn