【问题标题】:3 dimensional vector in c++ - partial definition of size before passing to functionc++中的3维向量-传递给函数之前的部分大小定义
【发布时间】:2012-05-21 12:00:01
【问题描述】:

我想定义一个 3 维向量,其中前两个维度是固定的,但我希望第三个向量由循环内调用的函数动态填充。

我不完全确定这是否被允许,但我已经尝试用类似的东西来实现它:

#define NUM 6

vector<vector<vector<double> > > foo;

foo.resize(NUM);
for(int j1=0; j1 < NUM; j1++){
    foo[j1].resize(NUM);
}

while(<condition>){
    fun(foo);
}

我将函数 fun 声明为

void fun(vector<vector<vector<double> > >& foo){
    for(int j1=0; j1<NUM; j1++){
        for(int j2=j1+1; j2<NUM; j2++){
             if(<condition>){
                   foo[j1][j2].push_back(<value>);
             }
         }
     }
 }

我最初测试了 NUM 等于 5 并且一切看起来都很好,但是当我尝试将其更改为 6 时,我遇到了分段错误。

我已经看到,即使我不尝试用 push_back 填充第三维(即我注释 push_back 行),对以 foo 作为参数的函数的简单调用也会弄乱 foo 的维度,也就是说,如果我插入一个

  cout << foo.size() << endl;

在while循环中,我看到foo的维度在第一次迭代后发生了变化,从NUM变为随机数。

我还发现这取决于平台,因为我在 Linux Ubuntu 上遇到了错误,但在 MacOSX 上却没有。所以我想我在做一些与内存分配有关的真正错误的事情,但我不知道到底是什么。有人可以向我解释一下吗?

感谢您的帮助!

【问题讨论】:

  • 如果您注释掉整个循环并尝试从fun 执行cout&lt;&lt;foo.size() 会发生什么?另外,您能否在调用函数中发布您在while(&lt;condition&gt;) 中使用的确切条件?在将 NUM 从 5 更改为 6 之后,您已经重新编译了所有内容(即,某些代码未使用 NUM 编译为 5,而其他一些代码使用 NUM 编译为 6 对吗?)
  • 您是否有一个简单的独立示例来解决问题?您的代码原样(除了fun 中的内部 for 循环 - 我认为这是故意的)看起来不错。
  • 此代码在发布时应该是有效的。您必须发布 SSCCE。
  • @Naveen 我试图评论 while 循环并在函数中调用 foo.size() ,它立即变成一个随机数,所以我不认为 while 循环是罪魁祸首.我有一个包含所有代码的 makefile,所以我认为所有内容都会同时重新编译。
  • 对我来说,3 维向量是具有 3 维的数学向量空间的一个元素。你可以用一个包含 3 个元素的简单数组来表示它,例如std::array&lt;double,3&gt;。在 C++ std::vectors 的上下文中,“3-dim 矢量”根本没有意义。无论如何,这些有点用词不当,它们只是动态数组,因此嵌套它们意味着每个元素可能具有不同的维度。这不是你想要的,考虑在单个std::vector 中创建一个模拟二维数组的类,并用std::vector&lt;double&gt;s 填充它。

标签: c++ memory-management resize segmentation-fault pass-by-reference


【解决方案1】:

您实际上可以使用向量构造函数创建一个具有固定数字大小的 3D 矩阵和所需大小的 2D 矩阵,该向量构造函数将元素的数量和用于复制以填充的元素作为参数向量。下面是它的外观:

#include <iostream>
#include <vector>

int main() {
    const size_t NUM = 6;
    std::vector< std::vector< std::vector<double> > > Matr(NUM, std::vector< std::vector<double> >(NUM, std::vector<double>()));
    std::cout << "num 2D matrices - " << Matr.size() << std::endl;
    for(size_t j1 = 0; j1 < Matr.size(); ++j1){
        std::cout << "num rows - " << Matr[j1].size() << std::endl;
        for(size_t j2 = 0; j2 < Matr[j1].size(); ++j2) {
            Matr[j1][j2].push_back(0.09l);
            std::cout << "num columns - " << Matr[j1][j2].size() << " ";
        }
        std::cout << std::endl;
    }
    return 0;
}

【讨论】:

    【解决方案2】:
    foo.resize(NUM);  
    for(int j1=0; j1 < NUM; j1++){  
        foo[j1].resize(NUM);
    }
    

    在这里您正在调整 foo[j1] 的大小,但 foo[j1] 中还没有任何内容..
    所以foo[j1] 还只是个垃圾。

    【讨论】:

    • 这样不行吗?我怎么能声明我已经知道的两个维度?
    • no..它不是..foo.resize(NUM) 将创建一个NUM 默认向量,所以foo[j1] 是完全有效的。
    • 哎呀~错过了...那应该没问题
    • 您也可以删除 for 循环并使用大小为 NUM 的向量 > 作为 foo.resize 的第二个参数。不要认为这会解决你原来的问题。 ;)
    猜你喜欢
    • 2021-11-22
    • 2015-01-11
    • 2020-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    相关资源
    最近更新 更多