代码之家  ›  专栏  ›  技术社区  ›  shoosh

C++:获取STD::向量的开始的地址?

  •  6
  • shoosh  · 技术社区  · 14 年前

    有时使用 std::vector 并暂时将该地址视为定期分配的缓冲区的地址。
    例如,替换为:

     char* buf = new char[size];
     fillTheBuffer(buf, size);
     useTheBuffer(buf, size);
     delete[] buf;
    

    用这个:

     vector<char> buf(size);
     fillTheBuffer(&buf[0], size);
     useTheBuffer(&buf[0], size);
    

    当然,这样做的好处是缓冲区是自动释放的,我不必担心 delete[] .

    我遇到的问题是当size==0时。在这种情况下,第一个版本可以正常工作。空缓冲区是“已分配”的,后续函数不执行任何操作,它们得到的大小为size==0。
    但是,如果在调用之后size==0,则第二个版本将失败 buf[0] 可能包含一个断言 0 < size .

    那么有没有其他的方法来代替这个成语呢 &buf[0] 即使向量是空的,也返回向量开始的地址?

    我也考虑过 buf.begin() 但根据标准,它甚至不能保证返回指针。

    4 回复  |  直到 8 年前
        1
  •  8
  •   UncleBens    14 年前

    我想你得检查一下。

    也许是一个效用函数:

    template <class T, class Alloc>
    T* data(std::vector<T, Alloc>& vec)
    {
        return vec.empty() ? 0 : &vec[0];
    }
    
    template <class T, class Alloc>
    const T* data(const std::vector<T, Alloc>& vec)
    {
        return vec.empty() ? 0 : &vec[0];
    }
    
        2
  •  1
  •   JoeG    14 年前

    虽然没有这个功能 std::basic_string data() 这正是你所需要的。

    你得用一些 buf.size()?&buf[0]:0;

        3
  •  1
  •   acanaday    14 年前

    我认为在这两种情况下你都应该安全。我认为vector::operator[int]和vector::at(int)之间的区别在于,[]运算符重载特别地 执行边界检查。使用buf[0]应该没有断言!

        4
  •  1
  •   Ben    14 年前

    如果您可以更改fillthebuffer并使用buffer获取一对迭代器,那么您将以标准库解决问题的方式来解决问题。