【问题标题】:Access vector of vector pointers向量指针的访问向量
【发布时间】:2021-12-10 02:20:29
【问题描述】:

我想用向量创建一个矩阵。在下面的代码中,我创建了一个向量,每个条目都包含一个指向另一个作为列的向量(myvector)的指针。我将随机值推送到 myvector(即列)。但是当我尝试访问数组的值时,它会在 cout 语句中弹出一个编译错误 "error: no match for 'operator*' (operand type is 'std::vector<int>')。我想知道如何访问这些值。我很确定这是一个幼稚的问题。

#include <iostream>
#include <vector>
using namespace std;
int main ()
{
  std::vector<vector<int>*> main;
  
  for(int j=0; j<3; j++){
        vector<int> *myvector = new vector<int>;
        main.push_back(myvector);
  }
  
  main[0]->push_back(1);
  main[0]->push_back(4);
  main[1]->push_back(6);
  main[1]->push_back(7);
  main[1]->push_back(8);
  main[2]->push_back(3);
   
  for(int j=0; j<3; j++){
    for(uint32_t i=0; i<main[j]->size(); i++)   
        std::cout<<main[j][i]<<" ";
    cout<<"\n";
  }
  
  return 0;
}

【问题讨论】:

  • 没关系。读错了。
  • main[j] 是一个指针,所以main[j][i] 中的[i] 迭代的是指针,而不是内部向量。我认为(*main[j])[i] 是您所追求的,但我已经严重误读了一次问题。
  • 附带问题,为什么是指向vector 的指针?这通常是个坏主意。
  • 你可以使用std::cout &lt;&lt; main[j]-&gt;at(i),但在你这样做之前问问自己为什么要使用指针。这段代码没有充分的理由。
  • 不要新建你的向量,这完全没有必要。向量已经动态地管理自己的内存。您唯一要做的就是增加一定程度的间接性并使您自己的事情变得更加困难。也看看这里:isocpp.github.io/CppCoreGuidelines/…

标签: c++ vector


【解决方案1】:

你本来可以做的

vector<vector<int>> main;

向量main的每个索引代表另一个向量

所以你可以在第一列输入一个数字

main[0].push_back = (_number_)

  • 要访问第一列第一行的数字,我们可以使用main[0][0]

【讨论】:

  • 虽然我在信息真空中同意这个答案,但提问者可能有一个非常罕见的合法案例之一,用于指向他们的 MRE 未表达的 vector 的指针。跨度>
  • 这是一个很好的建议,但您忽略了回答原来的问题
【解决方案2】:

这个例子展示了你在哪里寻找的语法,也展示了你应该如何使用 std::vector 而没有 new/delete。

#include <iostream>
#include <vector>
#include <memory>

// using namespace std; <== teach yourself NOT to do this.
// https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

void access_pointers_in_2d_vector()
{
    std::vector<std::vector<int>*> values; // don't call your variables main!

    for (int j = 0; j < 3; j++)
    {
        std::vector<int>* myvector = new std::vector<int>;
        values.push_back(myvector);
    }

    values[0]->push_back(1);
    values[0]->push_back(4);
    values[1]->push_back(6);
    values[1]->push_back(7);
    values[1]->push_back(8);
    values[2]->push_back(3);

    for (int j = 0; j < 3; j++)
    {
        for (uint32_t i = 0; i < values[j]->size(); i++)
        {
            //==================================================================
            // this is the syntax you're looking for
            // first dereference the pointer then use operator[] 
            std::cout << (*values[j])[i] << " ";
            //==================================================================
        }

        std::cout << "\n";
    }

    // don't forget to cleanup your memory!
    // if you typed new somewhere then there should
    // ALWAYS be a matching delete in your code too!
    for (int j = 0; j < 3; j++)
    {
        delete values[j]; // <<==== !!!!!!!
    }
}

// for dynamic memory managment new/delete aren't recommended anymore.
// use std::unique_pointer (or if your design really requires it std::shared_ptr)
void using_unique_pointer()
{
    // If you really need pointers, use std::unique_ptr
    // it will prevent you from introducing memory leaks
    const std::uint32_t size = 3ul;
    std::vector<std::unique_ptr<std::vector<int>>> values(size);
    for (auto& p : values)
    {
        p = std::make_unique<std::vector<int>>();
    }

    values[0]->push_back(1);
    values[0]->push_back(4);
    values[1]->push_back(6);
    values[1]->push_back(7);
    values[1]->push_back(8);
    values[2]->push_back(3);

  // output loop is same as for normal pointers.
   // no need to call delete, std::unique_ptr will do that for you
}

void without_pointers()
{
    // However your whole code in idiomatic c++ should look like this.
    // https://en.cppreference.com/w/cpp/container/vector/vector constructor (10)
    // https://en.cppreference.com/w/cpp/language/range-for these loops avoid bugs related to 
    // letting indices go out of bounds.

    std::cout << "\nusing (nested) initializer list and range based for loops : \n";
    std::vector<std::vector<int>> rows{ {1,4}, {6,7,8}, {3} };
    for (const auto& row : rows)
    {
        for (const auto& value : row)
        {
            std::cout << value << " ";
        }
        std::cout << "\n";
    }
}


int main()
{
    access_pointers_in_2d_vector();
    using_unique_pointer();
    without_pointers();
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-07
    • 2018-12-16
    • 2023-03-23
    • 2011-08-04
    • 1970-01-01
    • 2016-01-14
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多