在分配给指向固定数组的指针期间没有指针衰减

Posted

技术标签:

【中文标题】在分配给指向固定数组的指针期间没有指针衰减【英文标题】:No pointer decay during assignment to pointer-to-fixed array 【发布时间】:2017-05-25 18:38:15 【问题描述】:

我最近发现了指向固定数组的指针的语法。在尝试它时,我惊讶地发现指针衰减似乎不像下面的例子那样起作用:

#include <iostream>

int main( int argc, char* argv[] )

  char pa[3];
  //char (*parr)[3] = &pa; // This works.
  char (*parr)[3] = pa;    // This doesn't work - why?
  std::cout << (void*)pa << std::endl;
  std::cout << (void*)parr << std::endl;
  return 0;

输出:

prog.cpp: In function 'int main(int, char**)':
prog.cpp:10:21: error: cannot convert 'char*' to 'char (*)[3]' in initialization
char (*parr)[3] = pa;
       ^

使用 gcc-4.9.2 (Code Chef) 进行编译。

有人可以帮忙找出这里的问题吗?

更新

这是一个有趣但更令人费解的发现:如果编译 C 样式(我在 Code Chef 中选择“C”作为编译器,尽管它仍然显示 gcc-4.9.2。也许有传递不同的编译器标志以区分 C 和 C++ 编译。)

以上代码的C版本:

#include <stdio.h>

int main( int argc, char* argv[] )

  char pa[3];
  /* char (*parr)[3] = &pa; */
  char (*parr)[3] = pa;
  printf( "0x%x\n", pa);
  printf( "0x%x\n", parr);
  return 0;

编译后的 C 代码的输出:

0xbf92b1fd
0xbf92b1fd

【问题讨论】:

现代 C++ 有 std::arraystd::vector 时,为什么还要使用旧式 C 数组? 如果您使用的是 c++,请考虑改用std::array 【参考方案1】:

问题

char (*parr)[3] = pa;

parr 是一个指向数组的指针,它与指向数组第一个元素的指针不同(这是数组名称可以衰减的)。为了让它工作,你需要pa的地址像

char (*parr)[3] = &pa;

【讨论】:

你知道为什么 C++ 中的非工作指针衰减语法似乎在 C 样式代码中工作吗?我没想到这会成为 C 和 C++ 之间的差异点。 另外,您是说&amp;pa[0]&amp;pa 不同吗?我总是将它们互换使用,但我以前也从未使用过“指向固定数组的指针”语法。 在这种情况下,&amp;pa[0] 是指向第一个元素的 char*&amp;pa 是一个指向数组的char (*)[3]。它们具有相同的值但类型不同。 @StoneThrow 由于编译器扩展,它可以在 C 中为您工作。只有存在-pedantic-errors 时,GCC 才会拒绝它。 @StoneThrow &amp;pa&amp;pa[0] 是相同的地址,但类型不同 - 一个指向数组,一个指向该数组的元素。这类似于获取结构/类的地址与获取该结构/类的第一个数据成员的地址。

以上是关于在分配给指向固定数组的指针期间没有指针衰减的主要内容,如果未能解决你的问题,请参考以下文章

C指针:指向一个固定大小的数组

用指向数组的指针替换衰减的数组导致分段错误

数组衰减为指针的例外情况?

在 C 中声明指向结构的指针数组,但在需要之前不为结构分配内存

如何在 STL 中使用指向向量的指针,就像我们在将数组地址传递给另一个函数时将指针分配给数组一样?

C++中内存分配问题