c++: at what point should I start using "new char[N]" vs a static buffer "char[Nmax]"
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.
精彩评论