【问题标题】:merge two vector of void pointer (void *) into resulting new one将 void 指针 (void *) 的两个向量合并成新的向量
【发布时间】:2014-03-20 06:13:18
【问题描述】:

如果下面的合并令人困惑,这是我试图实现的高级方法:

我有两个向量 vector<void *>

说vectorA =具有三个元素:void * aa, void * ab, void *ac
和vectorB = 有三个元素:void * ba, void * bb, void *bc

组合为vectorC:三个元素:void * ca, void * cb, void *cc 其中 void * ca 是 aaba 的组合

我有以下代码将两个 std::vector 类型的向量合并为一个新的结果: 它是我班级的一部分(QuadTree)

void QuadTree::combineInsertData( const vector <void *> &data, size_t numDataTuples, const vector <void *> &addData, size_t numAddDataTuples, vector<void *> &resData){
    cout << "\t\t in combine Function" << endl;
    cout << " \t\tnumDataTuples: " << numDataTuples << endl;
    cout << " \t\tnumAddDataTuples: " << numAddDataTuples << endl;
    for (int c = 0; c != numCols_; c++) {
        resData[c] = malloc( (numDataTuples + numAddDataTuples) * colElemSizes_[c]);
        memcpy(resData[c] ,  data[c] , numDataTuples * colElemSizes_[c]);
        memcpy(resData[c] + numDataTuples , addData[c] , numAddDataTuples * colElemSizes_[c]);
    }
}

它似乎没有做它应该做的事情,我不知道为什么。 这是我的使用方法:(简单的手动测试)

   vector<void *> newInsertData;
    newInsertData.resize(numCols_, 0);  //numCols_ = 3 in my test case
    combineInsertData(insertData, numTuples, allSubdivData, subDivTupNum, newInsertData); 

    cout << "TEST TEST " << endl;
    cout << " insertData[0][400]" << *((double *)insertData[0] + 400) << endl;
    cout << " newInsertData[0][400]" << *((double *)newInsertData[0] + 400) << endl;

    cout << " insertData[0][5]" << *((double *)insertData[0] + 5) << endl;
    cout << " newInsertData[0][5]" << *((double *)newInsertData[0] + 5) << endl;
    cout << " insertData[0][499]" << *((double *)insertData[0] + 499) << endl;
    cout << " newInsertData[0][499]" << *((double *)newInsertData[0] + 499) << endl;

    cout << " allSubdivData[0][0]" << *((double *)allSubdivData[0] ) << endl;
    cout << " newInsertData[0][500]" << *((double *)newInsertData[0] + 500) << endl;
    cout << " allSubdivData[0][1]" << *((double *)allSubdivData[0] + 1) << endl;
    cout << " newInsertData[0][501]" << *((double *)newInsertData[0] + 501) << endl;

注意: 我是 C/C++ 新手,不胜感激。 在测试代​​码中,似乎只有第一个 memcpy 正在工作,而第二个没有(来自 combine 函数)。

??问题 ?? 是不是因为是void *所以行 resData[c] + numDataTuples 没有意义?至于偏移量应该在哪里?

这是打印出来的内容

TEST TEST                                                                                             |         CHUNK: writing -5.69494e+06
 insertData[0][400]-7.97392e+06                                                                       |         CHUNK: writing -3.51803e+06
 newInsertData[0][400]-7.97392e+06                                                                    |                tup index = 116
 insertData[0][5]-6.83384e+06                                                                         |         CHUNK: writing -5.43468e+06
 newInsertData[0][5]-6.83384e+06                                                                      |         CHUNK: writing -3.03083e+06
 insertData[0][499]-7.83881e+06                                                                       |                tup index = 131
 newInsertData[0][499]-7.83881e+06                                                                    |         CHUNK: writing -6.50737e+06
 allSubdivData[0][0]-6.86119e+06                                                                      |         CHUNK: writing -4.1256e+06
 newInsertData[0][500]649399                                                                          |                tup index = 132
 allSubdivData[0][1]-8.94236e+06                                                                      |         CHUNK: writing -6.67862e+06
 newInsertData[0][501]0    

已修复 错误在这一行:

memcpy(resData[c] + numDataTuples , addData[c] , numAddDataTuples * colElemSizes_[c]);

应该是

memcpy(resData[c] + numDataTuples * colElemSizes_[c] , addData[c] , numAddDataTuples * colElemSizes_[c]);这是我之前怀疑的。

【问题讨论】:

  • 你能概括地描述一下当你说“合并”时你想要做什么吗?我问的原因是很少有一个函数、一组函数、算法等可以做你想做的事情而不必重新发明轮子。
  • 只是我将两个 void 指针合二为一。除了我有 2 个 void 指针向量,其中第一个条目应与第一个条目组合,第二个条目应与第二个...等
  • 即使您进行了编辑,它仍然没有意义。指针只不过是一个整数值。所以忘记“指针”这个词——假装那些是整数。既然这些是整数,那么合并是什么意思?
  • 我在下面的其他评论中回答了您的问题。
  • 好吧,void 指针就像一个数组指针,但指向的数据类型一开始是未知的。

标签: c++ merge memcpy


【解决方案1】:

一个不错的选择是:

std::copy(data.begin(), data.end(), std::back_inserter(newInsertData));

总的来说,我鼓励将工作委派给 STL 容器。

【讨论】:

  • 不确定这是我需要的。我不想添加到数组中。我正在合并指针。
  • 通过合并指针我的意思是像合并两个数组。每个数组是void *
  • 您有一个值序列,另一个值序列,并且您想创建第三个值序列,该序列由第一个序列和第二个序列组成。这是你想要的吗?
  • 是的,这正是我所需要的
  • @Saher 指针不是数组。你不能像不能合并整数一样合并指针。
【解决方案2】:

试图了解你想要什么。所以从这个开始:

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

template <typename T>
std::vector<T> Combine(const std::vector<T>& v1, const std::vector<T>& v2)
{
   std::vector<T> result;
   std::copy(v1.begin(), v1.end(), std::back_inserter(result));
   std::copy(v2.begin(), v2.end(), std::back_inserter(result));
   return result;
}

int main()
{
   std::vector<void*> v1;
   std::vector<void*> v2;
   // assume that v1 and v2 have data
   //...
   std::vector<void*> r = Combine(v1, v2);
   // Now r has v1 and v2 combined as one vector.
}

诚然不是最好的,但如果这是您想要达到的目标,请注意使用 back_inserter 复制算法。您可以通过使用迭代器使代码更通用,而不是将其固定为仅使用向量,但我将其留给其他人改进。

【讨论】:

  • 为了更深入地了解 PaulMcKenzie 的代码,请阅读此处有关 back_inserter 的内容:cplusplus.com/reference/iterator/back_inserter
  • 这是否意味着如果 v1 有 3 个元素而 v2 有 3 个元素,那么结果将有 6 个?如果是这种情况,那么这不是我想要的,我希望结果仍然是 3。如果只是查看一列(例如第 0 列),并说 v1 在该列中分配了 10 个双精度,而 v2 分配了 30 个双精度。我希望结果能够将result[0][0] 索引到result[0][49]
  • 你知道,如果不是,这已经接近于 XY 问题:meta.stackexchange.com/questions/66377/what-is-the-xy-problem
【解决方案3】:

这一行的错误

memcpy(resData[c] + numDataTuples , addData[c] , numAddDataTuples * colElemSizes_[c]);

应该是

memcpy(resData[c] + numDataTuples * colElemSizes_[c] , addData[c] , numAddDataTuples * colElemSizes_[c]);

因为它是 void 指针,所以我猜它不知道复制从哪里开始。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-16
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-31
    • 2013-01-27
    相关资源
    最近更新 更多