【问题标题】:reference to pointer to int causes error引用指向 int 的指针会导致错误
【发布时间】:2012-10-02 18:00:13
【问题描述】:

我有以下一段代码,它是数组大小调整函数的实现。这似乎是正确的,但是当我编译程序时出现以下错误:

g++ -Wall -o "resizing_arrays" "resizing_arrays.cpp" (in directory: /home/aristofanis/Desktop/coursera-impl)
resizing_arrays.cpp: In function ‘int main()’:
resizing_arrays.cpp:37: error: invalid initialization of non-const reference of type ‘int*&’ from a temporary of type ‘int*’
resizing_arrays.cpp:7: error: in passing argument 1 of ‘void resize(int*&, int, int, int)’
resizing_arrays.cpp:39: error: invalid initialization of non-const reference of type ‘int*&’ from a temporary of type ‘int*’
resizing_arrays.cpp:7: error: in passing argument 1 of ‘void resize(int*&, int, int, int)’
resizing_arrays.cpp:41: error: invalid initialization of non-const reference of type ‘int*&’ from a temporary of type ‘int*’
resizing_arrays.cpp:7: error: in passing argument 1 of ‘void resize(int*&, int, int, int)’
Compilation failed.

代码如下:

int N=5;

void resize( int *&arr, int N, int newCap, int initial=0 ) { // line 7
  N = newCap;
  int *tmp = new int[ newCap ];
  for( int i=0; i<N; ++i ) {
    tmp[ i ] = arr[ i ];
  }
  if( newCap > N ) {
    for( int i=N; i<newCap; ++i ) {
      tmp[ i ] = initial;
    }
  }

  arr = new int[ newCap ];

  for( int i=0; i<newCap; ++i ) {
    arr[ i ] = tmp[ i ];
  }
}

void print( int *arr, int N ) {
  for( int i=0; i<N; ++i ) {
    cout << arr[ i ];
    if( i != N-1 ) cout << " ";
  }
}

int main() {
  int arr[] = { 1, 2, 3, 4, 5 };

  print( arr, N );
  resize( arr, N, 5, 6 ); // line 37
  print( arr, N);
  resize( arr, N, 10, 1 ); // line 39
  print( arr, N );
  resize( arr, N, 3 ); // line 41
  print ( arr, N );

  return 0;
}

谁能帮帮我?提前致谢。

【问题讨论】:

  • void resize( int *&amp;arr 这里去掉&amp;
  • @IonutHulub - 这会破坏函数的目的,即更改指针参数指向的数组的大小。
  • 没有*&amp;arr 这样的东西。你认为那是什么数据类型? arr 是一个指针,所以你不能在它上面调用 & ,即使你可以, * 撤消 & 的效果,因为一个用于引用,一个 if 用于取消引用。
  • @IonutHulub 实际上有。它是对指向 int 的指针的引用,它允许您更改指针及其指向的值。
  • 又是这样:“数组不是 C++ 中的指针”。

标签: c++ pointers reference int


【解决方案1】:

main,你声明

int arr[] = { 1, 2, 3, 4, 5 };

一个普通的数组,而不是 int*,这是你必须传递给 resize 的。

而且,虽然这对于您的 resize 的实现在技术上不是必需的,因为您从未在 delete[] 那里分配任何内存 - 您应该修复空间泄漏 - 您传递给 resize 的指针应该指向new-分配的内存块(你应该在resizedelete[])。

【讨论】:

  • 不可能调整静态数组的大小,因此这不是完全正确的建议,尽管您确实发现了问题。
  • 照原样,将任何int* 传递给resize 将泄漏但有效,resize 将使其指向不同的位置(丢失可能对旧块的最后引用)。
【解决方案2】:

arr 是一个分配在堆栈上的数组。你不能改变它的大小。如果您需要可调整大小的数组,请使用指针并使用new 分配数组。

【讨论】:

    【解决方案3】:

    数组不是指针。特别是,数组保持不变。你不能移动它。在您使用 poibters 的上下文中,您还会造成内存泄漏和越界访问。

    要创建一个可调整大小的数组,您需要维护一个指针,该指针最初是从数组中的元素副本设置的。就个人而言,我不会打扰并使用 std::vector&lt;int&gt;(除非我正在开发自己的标准 C++ 库并实现 std::vector&lt;T&gt;)。

    【讨论】:

      【解决方案4】:

      您收到特定错误的原因是arr 将衰减为使用时的临时int*。然后,您尝试将非常量引用(参数)绑定到临时值,这是非法的。见这里:

      How come a non-const reference cannot bind to a temporary object?

      【讨论】:

        【解决方案5】:

        当您说int&amp; 时,它意味着我可以更改其值的int 变量,同样,当您说int*&amp; 时,它意味着我可以更改其值的int* 变量。现在看看你的代码你能改变arr的值吗?说arr = new int[10] 合法吗?你看这是不合法的,在 C++ 术语中它不是 Lvalue(它不能位于等号运算符的左侧)并且所有非常量引用必须是 Lvalue

        【讨论】:

        • arrnew int[10] 都可以在等号运算符的右侧,并且所有可变引用都必须是左值
        • @MooingDuck 感谢您的评论,这是一个简单的错误!我的意思也是左值。再次感谢
        猜你喜欢
        • 2015-01-04
        • 2018-01-23
        • 1970-01-01
        • 2018-10-19
        • 2023-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多