Sao chép con trỏ trong vectơ khi tôi xóa con trỏ

lập trình


m_vBol.push_back(pbol);

delete pbol;

với mã này, vectơ của tôi có con trỏ null, tôi nghĩ đó là lý do tại sao tôi xóa pbol, nhưng tôi phải xóa nó, tôi phải làm thế nào?

Những gì tôi đã thử:

Tôi đã cố gắng tìm kiếm trên internet vì tôi không giải quyết được

Giải pháp 1

Chỉ để thêm vào những gì 0x01AA có – rất đúng – đã nói …
Việc sao chép con trỏ chỉ thực hiện điều đó – nó tạo bản sao địa chỉ của một mục chứ không phải bản sao của mục đó.
Và khi bạn gọi delete trên một con trỏ tới một mục bộ nhớ, bộ nhớ mà nó đang sử dụng sẽ được trả về vùng heap để sử dụng lại – điều đó có nghĩa là mọi bản sao của địa chỉ giờ đây có thể trỏ đến một cấu trúc hoàn toàn khác.

Ví dụ: nếu bạn malloc một mảng gồm 5 số nguyên, sao chép con trỏ, xóa nó và sau đó malloc một mảng gồm 100 số float, bản sao của con trỏ có thể truy cập vào mảng float và xáo trộn dữ liệu của mã khác.

Nếu bạn cần xóa một con trỏ, bạn có trách nhiệm đảm bảo rằng nó không còn được sử dụng nữa và không có bản sao nào của con trỏ có thể được truy cập sau đó – nếu không, các lỗi cực kỳ khó lường có thể bắt đầu xuất hiện trong mã không liên quan!

Giải pháp 2

Đoạn mã sau

C++
#include <iostream>
#include <vector>
using namespace std;

class Foo
{
  int m_value;
public:
  Foo(int i):m_value(i){}
  ~Foo(){ cout << "~Foo() called\n";}
  int get_value(){return m_value;}
};


int main()
{

  Foo * pfoo = new Foo(42);

  vector <Foo * > v;
  v.push_back(pfoo);

  cout << "pfoo " << pfoo << "\n";
  cout << "v[0] " << v[0] << "\n";
  cout << "v[0]->get_value() " << v[0]->get_value() << "\n";

  cout << "deleting pfoo\n";
  delete pfoo;
  cout << "setting pfoo=nullptr\n";
  pfoo = nullptr;

  cout << "pfoo " << pfoo << "\n";
  cout << "v[0] " << v[0] << "\n";
  cout << "v[0]->get_value() " << v[0]->get_value() << "\n";
}

sản xuất

pfoo 0x55de79f86eb0
v[0] 0x55de79f86eb0
v[0]->get_value() 42
deleting pfoo
~Foo() called
setting pfoo=nullptr
pfoo 0
v[0] 0x55de79f86eb0
v[0]->get_value() 0

trên hộp Linux của tôi (nó có thể tệ hơn).

Hãy nhìn vào con trỏ thông minh – cppreference.com[^].

Giải pháp 3

Ngoài giải pháp của Palini trong đó con trỏ được gói gọn trong một lớp hoặc cách khác là sử dụng con trỏ thông minh, cũng có thể chỉ cần xóa con trỏ không hợp lệ khỏi vectơ trước khi xóa nó. Sau đó nó sẽ không còn gây ra bất kỳ vấn đề gì nữa.

C++
m_vBol.erase(std::find(m_vBol.begin(), m_vBol.end(), pbol));
// or m_vBol.erase(std::remove(std::begin(m_vBol), std::end(m_vBol), pbol), std::end(m_vBol));
delete pbol;

Ngoài ra, bạn có thể ghi đè lên nó bằng nullptr.

コメント

タイトルとURLをコピーしました