【问题标题】:Pointer Dereference Of float ** unable to read memoryfloat ** 的指针取消引用无法读取内存
【发布时间】:2016-04-01 10:02:16
【问题描述】:

我有一个 C++ 类 Matrix2,它包含一个公共方法 foo() 和一个受保护的成员 m,在这里声明

 public:

 void foo();

 protected:

 float m[2][2];

假设数组 m 的全部内容在构造函数中初始化为零。

在另一个函数的某个地方,我在堆栈上声明了一个 Matrix2。

Matrix2 MAT;

然后,在同一个函数中,我调用了某个函数 foo,它是 Matrix2 类中的一个公共函数。

 MAT.foo();

在 foo() 中,我设置了

float ** u = (float **) m;

之后,在 foo 中,我打印出以下值。

 cout << "m :: " << u << endl;
 cout << "u :: " << m << endl;
 cout << "&m[0][0] :: " << &(m[0][0]) << endl;
 cout << "m[0][0] :: " << m[0][0] << endl;
 cout << "u[0][0] :: " << u[0][0] << endl;

结果:u的mem地址和m一样,也和&(m[0][0])一样。

使用 m[0][0] 取消对 m 的引用,该值按预期打印出来。

但是,使用 u[0][0] 取消对 u 的引用,程序崩溃并且无法读取内存,即使指针应该指向相同的位置。

关于为什么会这样的任何想法?

【问题讨论】:

  • 某种类型的数组的数组与指向某种类型的指针的指针相同。参见例如this old answer of mine 解释一下。
  • 您的m 不是浮点指针数组;它是浮点数的两项数组的两项数组,因此符号m(float [2])*,而不是float** 类型。如果您想在不使用数组语法的情况下转储数组值,您可以将m 转换为float*,假设整个数组内容存储在内存中的连续位置。但这是在自找麻烦……
  • 你已经在你的方法中犯了一个致命的错误:铸造。如果赋值的两侧不匹配,您应该考虑为什么会这样,并将任一侧更改为正确的类型,而不是应用蛮力(这相当于 C 样式强制转换),以便让编译器忽略这个错误。
  • 把石膏带走。重新编译。你得到什么编译器错误?演员表不会改变编译器错误告诉你的内容。您在使用强制转换时所做的只是使错误 message 消失——指针仍然不兼容,并且在运行程序时会看到结果。

标签: c++ pointers dereference


【解决方案1】:

确实,数组和指针在某种程度上可以互换,但它们需要引用相同的元素类型。这里,m 是 [float 的长度为 2 的数组] 的数组。如果要使用指针,只需使用正确的元素类型:

1 typedef float float_arr[2];
2 
3 
4 int main()
5 {
6     float m[2][2];
7                                                                                                                                                                                                          
8     float_arr *p = m;
9    
10     return 0;
11 }

【讨论】:

  • 了解何时需要使用演员表。你的问题是float ** u = (float **) m;。您需要在此处进行强制转换才能使其编译的事实应该是您出错的警告。
猜你喜欢
  • 2021-07-10
  • 1970-01-01
  • 2017-01-26
  • 2021-10-16
  • 2011-02-04
  • 2013-09-16
  • 1970-01-01
  • 2021-11-01
  • 2020-04-17
相关资源
最近更新 更多