开发者

c++: at what point should I start using "new char[N]" vs a static buffer "char[Nmax]"

开发者 https://www.devze.com 2023-01-01 05:39 出处:网络
My question is with regard to C++ Suppose I write a function to return a list of items to the caller. Each item has 2 logical fields: 1) an int ID, and 2) some data whose size may vary, let\'s say fr

My question is with regard to C++

Suppose I write a function to return a list of items to the caller. Each item has 2 logical fields: 1) an int ID, and 2) some data whose size may vary, let's say from 4 bytes up to 16Kbytes. So my question is whether to use a data structure like:

struct item {
  int  field1;
  char field2[M开发者_Go百科AX_LEN];

OR, rather, to allocate field2 from the heap, and require the caller to destroy when he's done:

struct item{
  int  field1;
  char *field2;  // new char[N] -- destroy[] when done!

Since the max size of field #2 is large, is makes sense that this would be allocated from the heap, right? So once I know the size N, I call field2 = new char[N], and populate it.

Now, is this horribly inefficient?

Is it worse in cases where N is always small, i.e. suppose I have 10000 items that have N=4?


You should instead use one of the standard library containers, like std::string or std::vector<char>; then you don't have to worry about managing the memory yourself.


The thing that's horribly in efficient is all the time you will waste tracking down memory leaks. Use classes that take care of this for you.

But if you don't want to do that:

suppose I have 10000 items that have N=4?

So you waste 40k of memory - your PC has at least a gigabyte, probably two, don't worry about it. A consistent interface, even if you're doing new/delete, is better than something fancy that will be harder to debug.

The only time when can safely use fixed-size buffers in production code is sizes are compile-time system constants, such as MAX_PATH.


You could do both:

struct item {
    ...
    char *field2; // Points to buf if < 8 chars (assuming null-terminator).
    char buf[8];
};

This does require some clever copy semantics, so you'll need a custom copy-constructor and assignment operator.

Alternatively, if item is always heap-allocated, you could ensure that item and its data are always allocated together:

struct item {
    ...
    char field2[1];
}

item* new_item(int size) {
    int offset = &((item*)0)->field2[0] - (char*)0;
    return new(malloc(offset + size)) item;
}


Actually it depends. As I see it:

statically sized buffer

Good

  • No need to manage memory
  • Very efficient in terms of execution speed

Bad

  • Might waste some memory

dynamically sized buffer

Good

  • Does not have to waste any memory, as the exact amount needed is known

Bad

  • Memory must be managed.
  • Might be slow(er)

With that in mind, and based on the situation (Is it likely sizes will vary much? Is execution speed extra important? ... ), pick one.

0

精彩评论

暂无评论...
验证码 换一张
取 消