关于指向stl的指针的新手问题

时间:2011-01-11 23:50:21

标签: c++ pointers stl vector

我写过这个函数

vector<long int>* randIntSequence(long int n) {
    vector<long int> *buffer = new vector<long int>(n, 0);
    for(long int i = 0; i < n; i++)
        buffer->at(i);

    long int j; MTRand myrand;
    for(long int i = buffer->size() - 1; i >= 1; i--) {
        j = myrand.randInt(i);
        swap(buffer[i], buffer[j]);
    }
    return buffer;
}

但是当我从main调用它时,myvec = randIntSequence(10),我看到myvector总是空的。我要修改返回值吗?

4 个答案:

答案 0 :(得分:5)

swap调用正在将*buffer指针编入索引,好像它是一个数组并且正在交换指针。你的意思是交换向量的项目。试试这个修改:

swap((*buffer)[i], (*buffer)[j]);

除此之外,您的at来电不会按预期设置值。您正在拉出矢量中的项目,但没有将它们设置为任何内容。尝试以下陈述之一:

buffer->at(i) = i;
(*buffer)[i] = i;

答案 1 :(得分:4)

您永远不会分配vector所指向的buffer中的任何元素:

for (long int i = 0; i < n; i++)
    buffer->at(i); // do you mean to assign something here?

您最终得到的vector包含n个零。

答案 2 :(得分:3)

您的问题已经得到解答,所以我会制作这个CW,但这就是您的代码的外观。

std::vector<long int> randIntSequence(long int n)
{
    std::vector<long int> buffer(n);
    for(int i=0; i<n; ++i)
        buffer[i] = i;
    std::random_shuffle(buffer.begin(), buffer.end());
    return buffer;
}

你绝对没有理由在这里使用指针。除非你有一些更高级的随机改组方法,否则你应该使用std::random_shuffle。您也可以考虑使用boost::counting_iterator初始化向量:

std::vector<long int> buffer(
    boost::counting_iterator<long int>(0),
    boost::counting_iterator<long int>(n));

虽然这可能有点矫枉过正。

答案 3 :(得分:1)

由于问题是关于STL的,所有你想要的是带有随机条目的向量:

std::vector<long int> v(10);
generate( v.begin(), v.end(), std::rand ); // range is [0,RAND_MAX]

// or if you provide long int MTRand::operator()()  
generate( v.begin(), v.end(), MTRand() );

但是如果你想修复你的功能那么

  • n应为size_t而不是long int
  • 第一个循环是no-op
  • 正如约翰所说,buffer是指针,因此buffer[0]是你的向量,buffer[i] i!=0是垃圾。看起来你很幸运能得到一个零大小的矢量而不是一个腐败的矢量!
  • 你打算随意洗牌吗?如果是的话,你就是在零附近徘徊。如果你只是想生成随机条目,那你为什么不循环向量(从0到缓冲区 - &gt; size(),而不是相反!!)并分配你的随机数?

C ++不是垃圾收集,你可能不希望智能指针用于这么简单的东西,所以你肯定会最终泄漏。如果原因在于生成堆向量并且通过指针返回是为了性能而避免复制,那么我建议不要这样做!以下是(几乎)完美的替代方案,包括清晰度和性能:

vector<T> randIntSequence( size_t n ) { 
   vector<T> buffer(n);
   // bla-bla
   return buffer; 
}

如果您认为此处存在多余的复制,请阅读this并信任您的编译器。