【问题标题】:why leads pointer cast from double*** to double** to a write access violation?为什么将指针从 double*** 转换为 double** 导致写访问冲突?
【发布时间】:2017-04-18 11:11:04
【问题描述】:

我必须集成来自 tetgen(网格生成器)的代码,这显然是经常使用的。但是,我必须使用旧版本(1.4.3 而不是 1.5),这给了我“写访问冲突”。 相关功能在这里:

void tetgenmesh::dummyinit(int tetwords, int shwords)
{
  unsigned long alignptr;

  // Set up 'dummytet', the 'tetrahedron' that occupies "outer space".
  dummytetbase = (tetrahedron *) new char[tetwords * sizeof(tetrahedron)
                                          + tetrahedrons->alignbytes];
  // Align 'dummytet' on a 'tetrahedrons->alignbytes'-byte boundary.
  alignptr = (unsigned long) dummytetbase;
  dummytet = (tetrahedron *)
    (alignptr + (unsigned long) tetrahedrons->alignbytes
     - (alignptr % (unsigned long) tetrahedrons->alignbytes));
  // Initialize the four adjoining tetrahedra to be "outer space". These
  //   will eventually be changed by various bonding operations, but their
  //   values don't really matter, as long as they can legally be
  //   dereferenced.
  dummytet[0] = (tetrahedron) dummytet;
  dummytet[1] = (tetrahedron) dummytet;
  dummytet[2] = (tetrahedron) dummytet;
  dummytet[3] = (tetrahedron) dummytet;
...
...
...
}

'dummytetbase'和'dummytet'都是双***指针,四面体是双**指针。

示例值为:

'tetwords' 是:12.

'(unsigned long)tetrahedrons->alignbytes' : 8.

'tetwords*sizeof( tetrahedron ) + tetrahedrons->alignbytes' 是:104。

'(alignptr % (unsigned long)tetrahedrons->alignbytes)' 是:0。

代码编译得很好,但是当指针从 'dummytet' 转换为 'dummytet[0]' 时,我得到了这个'写访问冲突'。

所以,dummytet 获得了 dummytetbase + 8 的地址。而且 dummytet[x] 获得了所有相同的地址,但这会导致写入冲突。

知道为什么会这样吗? 谢谢!

【问题讨论】:

  • 这是来自 tetgen 的原始代码。我一个字都没改……
  • 我将 'unsigned long' 替换为 'uint32_t',但写访问冲突仍然存在...
  • 如果不进行调试,很难判断到底发生了什么。或许试着找出维护图书馆的电子邮件地址。
  • 是的。虽然,在调试时,vs 只是告诉特定地址存在“写访问冲突”。
  • 您可以验证 dummytet 的结果指针是否在分配的内存中。此外,内存确实被正确分配并且足够大以容纳四面体

标签: c++ visual-studio pointers tetgen


【解决方案1】:

简单:double***double** 是完全不同的类型。 double*** 指向double**,而double** 指向double*。递归地应用这个逻辑。

现在由于两者都是指针,编译器将使用 32 位或 64 位。您可以告诉编译器闭嘴,消除差异,并在编译时忽略此问题。这意味着您的编译时问题现在具有运行时症状。

退一步:如果你有一个T* ptr 并且需要一个T 值,你就不要写(T) ptr。你写*ptr,或ptr[5],或类似的东西。这在T==double** 时仍然成立。

【讨论】:

  • 是的,我明白你的意思。但这意味着 tetgen 代码有一个内置错误......这个版本已经存在 7 年了,已经在几个程序中找到了它的方式......到目前为止没有人抱怨?所以,你说,这种用对应的双***指针的地址来初始化双**指针的技术一般是无效的,对吧?如果我现在看,这对我来说也是合理的。
  • @sciloop:编译器难以置信很挑剔,所以我也会。 “用地址相应的双***指针初始化double**指针”是另一个问题。 double*** 的地址是 double****。那是 4 星,是我们以前在这个问题中没有见过的类型。您不能使用 double***double**** 初始化 double**
  • 啊,是的,对不起'双***的地址......那么,如果那不可能的话,tetgen创造者的意图是什么。如果我正确理解了代码,那么不会为 double** 指针保留内存,对吧?这是否意味着代码通常不起作用?
  • @sciloop:代码确实似乎无效,并且表现出未定义的行为。但看起来问题可能只会在更高的优化级别下出现,当优化器应用诸如“这个double**不能指向那个double**,因为double**只能指向double*。所以dummytet[0] 不能等于 dummytet"。较旧的编译器没有如此智能的优化器,所以这或许可以解释为什么代码在过去似乎可以工作。
  • 好的,所以我无能为力,因为优化已设置为“禁用 (/Od)”。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多