2

我在课堂上的私有变量上遇到了一个非常奇怪的行为。

问题描述:类lapi_xmeef_table中私有成员“current”的值在成员函数结束时异常改变。

类 1:lapi_xmeef 类 2:lapi_xmeef_table(是 lapi_xmeef 的朋友,因此可以直接或通过公共接口访问 lapi_xmeef 中的私有变量)

class lapi_xmeef {
  friend class lapi_xmeef_table;
  ...
  short bias_frag_layer;
  int bias_frag_index;
  ...
  public:
    // Add constructor
    lapi_xmeef();
    // Add public interface
    ...
    void bias_frag(int *li, int *fi);

};

class lapi_xmeef_table {
  private:
    lapi_xmeef *current;
    ...
  public:
    lapi_xmeef_table(Lapi_ctl *ctl, int num_layer);
    ...
    void get_bias(int *li, int *fi);
    ...
}; 

lapi_xmeef_table 中称为“current”的私有变量是当前迭代器(lapi_xmeef 类)。

成员函数除了只读之外什么都不做,它从其私有成员中复制两个值。如下图所示

void lapi_xmeef::bias_frag(int *li, int *fi)
{
   *li = (short)bias_frag_layer;
   *fi = bias_frag_index;
}

问题函数和变量:

void lapi_xmeef_table::get_bias(int *li, int *fi)
{
// current is (lapi_xmeef *) 0x2a9a93c7f0 (a valid address)
  current->bias_frag(li, fi);
// current is (lapi_xmeef *) 0x2a000000df (a invalid address)
}

调用函数前 current is (lapi_xmeef *) 0x2a9a93c7f0 (a valid address) 之后,current is (lapi_xmeef *) 0x2a000000df (a invalid address)

每次调用成员函数时都不会发生这种情况,在这种奇怪的行为之前,它被多次调用而没有问题。

下次访问 current 中的成员时,由于取消引用无效地址而发生 seg 错误。

现在我的解决方案是在调用其成员函数之前有一个临时指针来保存 current 的值,然后在调用后恢复它。有用。

void lapi_xmeef_table::get_bias(int *li, int *fi)
{
  lapi_xmeef *temp = current;
  current->bias_frag(li, fi);
  current = temp;
}

但我真的很想知道为什么以及如何解决它,而不是这种棘手的方式。

为什么私有变量的值被改变,预期是相同的?

访问私有变量的方式有什么问题吗?是需要前缀还是需要点“this”?我试过这个->current->bias_frag(li, fi); 这没有帮助。

先感谢您。

4

1 回答 1

1

可能发生的情况是您正在进行意外的指针别名lior指针之一fi指向与 相同的位置&current,因此当您在 内部取消引用并分配给它们时bias_frag,您会不小心覆盖current它或它的一部分。

要修复它,您需要通过向后跟踪数据流来弄清楚为什么会得到别名指针。对于初学者,提高编译器的警告级别并修复所有警告。

不要试图通过保存current和恢复它的价值来解决它——这只是一个更大的问题的绷带,而不是一个长期的解决方案。你已经进入了未定义行为的领域,试图把自己挖出来是行不通的。

于 2012-11-15T15:49:45.810 回答