字符数组的最佳替代品

时间:2009-03-06 07:21:32

标签: c++ data-structures

我们有一个数据结构

struct MyData
{
       int length ;
       char package[MAX_SIZE];  
};

其中MAX_SIZE是固定值。现在我们想要改变它以便支持 “无限”包长度大于MAX_SIZE。建议的解决方案之一 是用指针替换静态数组然后动态分配 我们要求的尺寸为EX

struct MyData
{
       int length ;
       char* package;  
};

然后

package = (char*)malloc(SOME_RUNTIME_SIZE) ;

现在我的问题是,这是满足要求的最有效方式还是有任何其他方法......可能使用STL数据结构,如可增长数组等。 我们想要一个解决方案,其中大多数适用于静态char数组的代码也适用于新结构..

9 个答案:

答案 0 :(得分:7)

更好,更好/更安全:

struct my_struct
{
    std::vector<char>package;  
};

要调整大小:

my_struct s;
s.package.resize(100);

要看它有多大:

my_struct s;
int size = s.package.size();

您甚至可以将函数放在结构中以使其更好:

struct my_struct
{
  std::vector<char>package;  

  void resize(int n) {
    package.resize(n);
  }
  int size() const {
    return package.size();
  }
};

my_struct s;
s.resize(100);
int z = s.size();

在你知道它之前,你正在编写好的代码......

答案 1 :(得分:4)

  

使用可扩展数组等STL数据结构

STL为您提供了大量容器。不幸的是,选择取决于您的要求。您多久添加一次容器?你删除了多少次?你从哪里删除/添加?你需要随机访问吗?你需要什么样的保证?一旦您对这些事情有足够清晰的认识,请查看vectordequelistset等。

如果您可以提供更多细节,我们肯定可以帮助您选择一个合适的细节。

答案 2 :(得分:2)

我还会包裹一个矢量:

// wraps a vector. provides convenience conversion constructors
// and assign functions. 
struct bytebuf {
    explicit bytebuf(size_t size):c(size) { }

    template<size_t size>
    bytebuf(char const(&v)[size]) { assign(v); }

    template<size_t size>
    void assign(char const(&v)[size]) {
        c.assign(v, v+size);
    }

    // provide access to wrapped vector
    std::vector<char> & buf() {
        return c;
    }

private:
    std::vector<char> c;
};

int main() {
    bytebuf b("data");
    process(&b.buf()[0], b.buf().size()); // process 5 byte

    std::string str(&b.buf()[0]);
    std::cout << str; // outputs "data"

    bytebuf c(100);
    read(&c.buf()[0], c.buf().size()); // read 100 byte
    // ...
}

我认为没有必要为它添加更多功能。您始终可以使用buf()获取向量并直接对其进行操作。由于向量的存储是连续的,您可以像C数组一样使用它,但它仍然可以调整大小:

c.buf().resize(42)

模板转换构造函数和assign函数允许您直接从C数组初始化或赋值。如果愿意,可以添加更多可以从一组两个迭代器或指针和长度初始化的构造函数。但我会尝试保持较低的附加功能,因此它仍然是一个紧凑,透明的矢量包装结构。

答案 3 :(得分:2)

如果是C:

答案 4 :(得分:2)

如果您将字符数组用作字符数组,请使用std::vector<char>作为矢量的用途。如果您将字符数组用作字符串,请使用std::string,它将以与std::vector<char>几乎相同的方式存储其数据,但会更清楚地传达其目的。

答案 5 :(得分:1)

是的,我会使用STL向量:

struct
{
    std::vector<char> package;
    // not sure if you have anything else in here ?
};

但你的struct length成员只是变成了package.size()。

您可以像在原始char数组(package [index])中那样索引向量中的字符。

答案 6 :(得分:1)

使用双端队列。确定一个向量会工作并且很好,但是一个双端队列将使用碎片存储器并且几乎一样快。

答案 7 :(得分:0)

你是如何使用你的结构的呢? 它是像数组还是像字符串一样?

我只想输入一个C ++容器:

typedef  std::string  MyData; // or std::vector<char> if that is more appropriate

答案 8 :(得分:-1)

如果您不需要动态调整大小,您所编写的内容可以正常工作,这可能是最好的选择。如果您发现需要扩展阵列,则可以运行

package = (char*)realloc((void*)package, SOME_RUNTIME_SIZE) ;

您可以使用STL矢量

include <vector>

std::vector<char> myVec();  //optionally myVec(SOME_RUNTIME_SIZE)

然后您可以使用myVec.resize(newSize)或使用添加到向量并自动调整大小的push_back等函数来调整大小。向量解决方案的好处在于它消除了许多内存管理问题 - 如果向量是堆栈分配的,它的析构函数将在超出范围时被调用,并且它下面的动态分配的数组将被删除。但是,如果你传递向量,数据将被复制,这可能很慢,所以你可能需要将指针传递给向量。