为什么当我设置指向等于 NULL 的对象的指针时会出现分段错误



好的,所以我有一个本质上运行市场模拟的程序。我的很多程序都运行良好,我只有一个问题。在我的程序中,我有一个像这样的检查器结构:

 14 struct Checker
 15 {
 16  int m_money_in_register;
 17  int m_start_work;
 18  int m_time_checkout;
 19  Cust *m_cust;
 20 };

我创建一个指向检查器对象数组的指针,如下所示:

118 Checker *checkers = new Checker[num_checkers]; // Initializing all checkers
119  for(int i = 0; i < num_checkers; i++)
120  {
121   checkers[i].m_money_in_register = 500;
122   checkers[i].m_start_work = 0;
123   checkers[i].m_cust = NULL;
124   checkers[i].m_time_checkout = 0;
125  }

这工作得很好,当检查器[i].m_cust = NULL时,这意味着检查器可用,我可以将我checkout_queue中的Cust对象分配给检查器。

我的程序为第一个检出的 Cust 执行我希望它执行的操作,但是当该 Cust 完成检出时,我想设置检查器[i].m_cust = NULL,以便它再次可供客户使用,但是,这给了我一个分段错误,如下所示:

195 if(checkers[i].m_time_checkout == clock && checkers[i].m_cust->get_status() == "shopper" && checkers[i].m_cust != NULL)
196      {
197       int amount_paid = checkers[i].m_cust->get_num_items()*5;
198       checkers[i].m_money_in_register += amount_paid;
199       checkers[i].m_cust->print_done_checkout(cout, clock, amount_paid, i);
200       Cust *tmp = checkers[i].m_cust;
201       delete tmp;
202       num_custs--;
203       checkers[i].m_cust = NULL; // SEG FAULT CAUSED BY THIS
204      }
205
206      if(checkers[i].m_time_checkout == clock && checkers[i].m_cust->get_status() == "robber" && checkers[i].m_cust != NULL)
207      {
208       int checker_cash = checkers[i].m_money_in_register;
209       checkers[i].m_cust->print_done_stole(cout, clock, checker_cash, i);
210       checkers[i].m_money_in_register = 0;
211       Cust *tmp = checkers[i].m_cust;
212       delete tmp;
213       num_custs--;
214       checkers[i].m_cust = NULL; // SEG FAULT CAUSED BY THIS
215      }

如何正确将对象设置为 NULL? 输出 IM 获取的示例如下所示:

1: Joe entered store
Should be done at: 7
2: James entered store
Should be done at: 8
3: Bob entered store
Should be done at: 9
4: Abby entered store
Should be done at: 10
5: Leo entered store
Should be done at: 11
7: Joe done shopping
7: Joe started checkout with checker 0
time checkout: 13
8: James done shopping
8: James started checkout with checker 1
time checkout: 14
9: Bob done shopping
10: Abby done shopping
11: Leo done shopping
13: Joe paid $10 for 2 items to checker 0
Segmentation fault

就像我说的,第 13 行是我想要发生的,但是将指向 Cust 对象的指针设置为等于 null 会给我 seg 错误。如果需要进一步澄清,或者您想要GDB消息,我可以提供。任何意见不胜感激,谢谢!


整个循环如下:

175    for(int i = 0; checker_queue.empty() != true && i < num_checkers; i++)
176    {
177      int checker_number = i;
178      if(checkers[i].m_cust == NULL && checkers[i].m_start_work == 0)
179      {
180       checkers[i].m_cust = checker_queue.dequeue();
181       checkers[i].m_cust->print_start_checkout(cout, clock, checker_number);
182
183      if(checkers[i].m_cust->get_status() == "shopper")
184       {
185        checkers[i].m_time_checkout = clock + (checkers[i].m_cust->get_num_items()*3);
186       }
187
188       else if(checkers[i].m_cust->get_status() == "robber")
189       {
190        checkers[i].m_time_checkout = clock + 7;
191       }
192       cout << "time checkout: " << checkers[i].m_time_checkout << endl; //check for checkout time
193      }
194
195      if(checkers[i].m_time_checkout == clock && checkers[i].m_cust->get_status() ==    "shopper" && checkers[i].m_cust != NULL)
196      {
197       int amount_paid = checkers[i].m_cust->get_num_items()*5;
198       checkers[i].m_money_in_register += amount_paid;
199       checkers[i].m_cust->print_done_checkout(cout, clock, amount_paid, i);
200       Cust *tmp = checkers[i].m_cust;
201       delete tmp;
202       num_custs--;
203       checkers[i].m_cust = NULL;
204      }
205
206      if(checkers[i].m_time_checkout == clock && checkers[i].m_cust->get_status() == "robber" && checkers[i].m_cust != NULL)
207      {
208       int checker_cash = checkers[i].m_money_in_register;
209       checkers[i].m_cust->print_done_stole(cout, clock, checker_cash, i);
210       checkers[i].m_money_in_register = 0;
211       Cust *tmp = checkers[i].m_cust;
212       delete tmp;
213       num_custs--;
214       checkers[i].m_cust = NULL;
215      }
216     }

如果我注释掉设置跳棋[i].m_cust = NULL,我会得到更多的输出,如下所示:

1: Joe entered store
Should be done at: 7
2: James entered store
Should be done at: 8
3: Bob entered store
Should be done at: 9
4: Abby entered store
Should be done at: 10
5: Leo entered store
Should be done at: 11
7: Joe done shopping
7: Joe started checkout with checker 0
time checkout: 13
8: James done shopping
8: James started checkout with checker 1
time checkout: 14
9: Bob done shopping
10: Abby done shopping
11: Leo done shopping
13: Joe paid $10 for 2 items to checker 0
14: James paid $10 for 2 items to checker 1
Segmentation fault

我怀疑问题是您正在测试优化的代码,因此崩溃发生位置的表示不正确。问题可能是 if 语句中的以下代码:

checkers[i].m_cust->get_status() == "robber" && checkers[i].m_cust != NULL

你有错误的方式;在尝试调用get_status()之前,你需要检查m_cust不是空

checkers[i].m_cust != NULL && checkers[i].m_cust->get_status() == "robber"

if(checkers[i].m_time_checkout == clock && checkers[i].m_cust != NULL && checkers[i].m_cust->get_status() == "robber")

当给定两个逻辑 AND 条件时:

如果 ( a && b )

b只需要检查a是否为真。C 和 C++ 一旦达到使其余测试变得不必要的条件,就会停止评估条件(称为"短路评估")。

if ( a ||(b&&c) )

如果 a 为 true,则不会计算 b 和 c。 只有当a为假而b为真时,才会评估c

--旁白--

Cust *tmp = checkers[i].m_cust;
delete tmp;

我猜这是你"这里发生了什么"调查的一部分,但你应该没问题

delete checkers[i].m_cust;

只要对象检查器[i].m_cust单独分配了"new"。确保你没有做

Customers* customer = new Customer[someNumber];
...
checkers[i].m_cust = customer[x];
...
delete checkers[i].m_cust;  // << BAD

如果您的客户像这样进行阵列分配,请不要单独删除它们,而是使用

delete [] customers;

当你用完它们时。

相关内容

  • 没有找到相关文章

最新更新