指针引用不同的值

Posted

技术标签:

【中文标题】指针引用不同的值【英文标题】:Pointer refer different values 【发布时间】:2021-02-14 09:28:59 【问题描述】:

我在hackerrank 中解决初学者C++ 挑战时遇到了问题。 https://www.hackerrank.com/challenges/variable-sized-arrays/problem

挑战要求我创建一个简单的 2d 数组的 int 数组数组,但输入约束的顺序非常糟糕,我无法做到。突然,我想到了创建一个指针数组*arrA,每个元素引用其子数组arrB&arrB[0]

注意:类似于vector<vector<int>>,但我不会在这里使用vector

int main() 
    int n, q, k, i, j;
    cin >> n >> q;
    
    int *arr[n];
    for (int l = 0; l < n; l++) 
        cin >> k;
        int arr_i[k];
        for (int m = 0; m < k; m++) 
            cin >> arr_i[m];
        
        arr[l] = &arr_i[0];
        cout << *arr[l] << " " << arr[l] << endl;
    
    // after 2 loop, it prints
    // 1 0x7fff17940030
    // 2 0x7fff17940020
    
    for (int l = 0; l < q; l++) 
        cin >> i >> j;
        cout << *arr[l] << " " << arr[l] << endl;
    
    
    // after 2 loop, it prints
    // random integer(eg: 395575472) 0x7fff17940030
    // random integer(eg: 922493088 ) 0x7fff17940020
    return 0;

约束是:

2 2           // n q
3 1 5 4       // k k[0] k[1] k[2]
5 2 2 8 9 3   // k k[0] k[1] k[2] k[3] k[4]
0 1           // i j
1 3           // i j

回到问题,第一个循环打印出我需要的内容。但是在第二个循环中,尽管地址相同,但缺少值。我搜索了许多 *** 问题,但没有一个符合我的需求。

谁能给我解释一下。非常感谢!!!

【问题讨论】:

int *arr[n]; 是 VLA 而非标准 C++。使用std::vector。此外,int arr_i[k]; 是一个临时对象。所以它在作用域的末尾被销毁。您的指针指向不存在的对象。 你为什么不使用std::vector 您正在将临时变量的地址添加到主数组中,因此每次它们超出范围时,您都会得到 垃圾。这可以通过使用数组和push_back 来解决。 std::vector&lt;std::vector&lt;int&gt;&gt; 可以接受带有push_back 的整行。 为什么不使用vector&lt;vector&lt;int&gt;&gt;?现在,您正在使用容易出错的技术和非标准扩展。 @f*** 一些编译器允许这样做,但它是非标准的。 【参考方案1】:

int arr_i[k]; 的范围是第一个循环,虽然可以将其地址与arr[l] = &amp;arr_i[0]; 一起使用,但当您在第二个循环中取消引用它们时,这些地址超出了范围。

【讨论】:

虽然我得到了本地数组的地址。访问它不是同一个地址吗? 地址没有变化(如您的示例所示),但它们引用的内容发生了变化。尊重一个杂散的指针可能会导致段错误、垃圾数据,或者碰巧有你期望的数据。第二个循环变量 l 可能被分配在堆栈上以覆盖数据,或者 cin/cout 中涉及的函数调用现在可能有它们的参数或返回地址。 感谢您的清晰解释。我终于明白了。【参考方案2】:

拥有可变大小数组的 C++ 方法是 std::vector。你可以有一个向量的向量。 示例:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main() 
    int nrOfVectors, q /* what is q?*/;
    std::cin >> nrOfVectors >> q;
    std::vector<std::vector<int>> vecvec(nrOfVectors);
    for(auto& vec : vecvec) 
        int nrOfElements;
        std::cin >> nrOfElements;
        vec.reserve(nrOfElements);
        std::copy_n(std::istream_iterator<int>(std::cin), nrOfElements, back_inserter(vec));
    

编辑: 数组解决方案没有附加价值(实际上使事情变得不必要的复杂和容易出错),但无论如何

#include <iostream>
#include <memory>


int main() 
    int nrOfVectors, q /* what is q?*/;
    std::cin >> nrOfVectors >> q;
    std::unique_ptr<std::unique_ptr<int[]>[]> vecvec(new std::unique_ptr<int[]>[nrOfVectors]);
    for (int i = 0; i < nrOfVectors; ++i) 
        int nrOfElements;
        std::cin >> nrOfElements;
        auto vec = new int[nrOfElements];
        for (int j = 0; j < nrOfElements; ++j) 
            std::cin >> vec[j];
        
        vecvec[i].reset(vec);
    

【讨论】:

我想尝试一下使用数组,因为向量使这个挑战很容易解决。 @iamphduc 你在听到自己的声音吗? “我想尝试一下使用数组,因为矢量使这个挑战很容易解决。”然而你来这里是为了答案......不要让自己过得艰难。 试着练习数组并弄清楚事情是如何工作的。无论如何,感谢您花时间回答我的问题。

以上是关于指针引用不同的值的主要内容,如果未能解决你的问题,请参考以下文章

二维数组名和二级指针

第三次作业

引用 指针 解引用

2.3.2练习

JAVA中 如何把一个数组里的值去除掉

C中“引用”和“取消引用”的含义