C++ 动态分配C结构?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1979879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically allocate C struct?
提问by pf.
I want to dynamically allocate a C struct:
我想动态分配一个 C 结构:
typedef struct {
short *offset;
char *values;
} swc;
Both 'offset' and 'values' are supposed to be arrays, but their size is unknown until runtime.
'offset' 和 'values' 都应该是数组,但它们的大小直到运行时才知道。
How can I dynamically allocate memory for my struct and the struct's arrays?
如何为结构体和结构体的数组动态分配内存?
回答by spurserh
swc *a = (swc*)malloc(sizeof(swc));
a->offset = (short*)malloc(sizeof(short)*n);
a->values = (char*)malloc(sizeof(char)*n);
Where n = the number of items in each array and a is the address of the newly allocated data structure. Don't forget to free() offsets and values before free()'ing a.
其中 n = 每个数组中的项数,a 是新分配的数据结构的地址。不要忘记在 free() 之前释放 () 偏移量和值。
回答by John Bode
In C:
在 C 中:
swc *s = malloc(sizeof *s); // assuming you're creating a single instance of swc
if (s)
{
s->offset = malloc(sizeof *(s->offset) * number_of_offset_elements);
s->values = malloc(sizeof *(s->values) * number_of_value_elements);
}
In C++:
在 C++ 中:
try
{
swc *s = new swc;
s->offset = new short[number_of_offset_elements];
s->values = new char[number_of_value_elements];
}
catch(...)
{
...
}
Note that in C++, you might be better off using vectors as opposed to dynamically allocated buffers:
请注意,在 C++ 中,最好使用向量而不是动态分配的缓冲区:
struct swc
{
std::vector<short> offset;
std::vector<char> values;
};
swc *a = new swc;
Question: is values supposed to be an array of individual characters or an array of strings? That would change things a bit.
问题:值应该是单个字符数组还是字符串数组?那会改变一些事情。
EDIT
编辑
The more I think about it, the less satisfied I am with the C++ answer; the rightway to do this sort of thing in C++ (assuming you needdynamically allocated buffers as opposed to vectors, which you probably don't) is to perform the memory allocation for offset and values as part of a constructor within the struct type, and have a destructor deallocate those elements when the struct instance is destroyed (either by a delete
or by going out of scope).
我想得越多,我对 C++ 的回答就越不满意;在 C++ 中做这种事情的正确方法(假设你需要动态分配的缓冲区而不是向量,你可能不需要)是作为结构类型中构造函数的一部分执行偏移和值的内存分配,并让析构函数在 struct 实例被销毁(通过 adelete
或超出范围)时释放这些元素。
struct swc
{
swc(size_t numOffset = SOME_DEFAULT_VALUE,
size_t numValues = SOME_OTHER_DEFAULT_VALUE)
{
m_offset = new short[numOffset];
m_values = new char[numValues];
}
~swc()
{
delete[] m_offset;
delete[] m_values;
}
short *m_offset;
char *m_values;
};
void foo(void)
{
swc *a = new swc(10,20); // m_offset and m_values allocated as
// part of the constructor
swc b; // uses default sizes for m_offset and m_values
...
a->m_offset[0] = 1;
a->m_values[0] = 'a';
b.m_offset[0] = 2;
b.m_values[0] = 'b';
...
delete a; // handles freeing m_offset and m_values
// b's members are deallocated when it goes out of scope
}
回答by JoeG
You have to do it seperately. First allocate the struct, then the memory for the arrays.
你必须单独做。首先分配结构,然后为数组分配内存。
In C:
在 C 中:
swc *pSwc = malloc(sizeof(swc));
pSwc->offset = malloc(sizeof(short)*offsetArrayLength);
pSwc->values = malloc(valuesArrayLength);
In C++, you shouldn't be doing anything like that.
在 C++ 中,你不应该做这样的事情。
回答by Martin York
In C:
在 C 中:
typedef struct
{
short *offset;
char *values;
} swc;
/// Pre-Condition: None
/// Post-Condition: On failure will return NULL.
/// On Success a valid pointer is returned where
/// offset[0-n) and values[0-n) are legally de-refrancable.
/// Ownership of this memory is returned to the caller who
/// is responsible for destroying it via destroy_swc()
swc *create_swc(unsigned int size)
{
swc *data = (swc*) malloc(sizeof(swc));
if (data)
{
data->offset = (short*)malloc(sizeof(short)*n);
data->values = (char*) malloc(sizeof(char) *n);
}
if ((data != NULL) && (size != 0) && ((data->offset == NULL) || (data->values == NULL)))
{
// Partially created object is dangerous and of no use.
destroy_swc(data);
data = NULL;
}
return data;
}
void destroy_swc(swc* data)
{
free(data->offset);
free(data->values);
free(data);
}
In C++
在 C++ 中
struct swc
{
std::vector<short> offset;
std::vector<char> values;
swc(unsigned int size)
:offset(size)
,values(size)
{}
};
回答by dmckee --- ex-moderator kitten
One thing to add to the many correct answers here: you canmalloc
an over-sized structure to accommodate a variable sized array in the last member.
在这里要添加到许多正确答案中的一件事:您可以malloc
使用超大结构以在最后一个成员中容纳可变大小的数组。
struct foo {
short* offset;
char values[0]
};
and later
然后
struct *foo foo1 = malloc(sizeof(struct foo)+30); // takes advantage of sizeof(char)==1
to get room for 30 objects in the values
array. You would still need to do
为values
阵列中的30 个对象腾出空间。你仍然需要做
foo1->offsets = malloc(30*sizeof(short));
if you want them to use the same size arrays.
如果您希望它们使用相同大小的数组。
I generally wouldn't actually do this (maintenance nightmare if the structure ever needs to expand), but it is a tool in the kit.
我通常实际上不会这样做(如果结构需要扩展,维护噩梦),但它是工具包中的一个工具。
[code here in c. You'll need to cast the malloc
's (or better use new
and RAII idioms) in c++]
[这里的代码是c。您需要在 C++ 中转换malloc
's(或更好的使用new
和 RAII 习语)]
回答by DaveC
You will need a function to do this. Something like (my C/C++ is rusty)
您将需要一个函数来执行此操作。类似的东西(我的 C/C++ 生锈了)
swc* makeStruct(int offsetCount, int valuesCount) {
swc *ans = new swc();
ans->offset = new short[offsetCount];
ans->values = new char[valuesCount];
return ans;
}
myNewStruct = makeStruct(4, 20);
Syntax may be a bit off but that is generally what you are going to need. If you're using C++ then you probably want a class with a constructor taking the 2 args instead of the makeStruct but doing something very similar.
语法可能有点偏离,但这通常是您需要的。如果您使用的是 C++,那么您可能想要一个带有构造函数的类,该类使用 2 个 args 而不是 makeStruct 但做一些非常相似的事情。
回答by warp
swc* a = malloc(sizeof(*a));
a->offset = calloc(n, sizeof(*(a->offset)));
a->values = calloc(n, sizeof(*(a->values)));
You should not cast void* in c... in c++ you must!
你不应该在 c 中转换 void*... 在 c++ 中你必须!
回答by Ashish
Use malloc function or calloc to allocate memory dynamically . and search it on google to get examples.
使用 malloc 函数或 calloc 动态分配内存。并在谷歌上搜索以获取示例。
The calloc function initializes allocated memory to zero.
回答by pyon
Most of the answers are correct. I would like to add something that you haven't explicitly asked but might also be important.
大多数答案是正确的。我想添加一些您没有明确要求但可能也很重要的内容。
C / C++ arrays don't store their own size in memory. Thus, unless you want offset
and values
to have compile-time defined values (and, in that case, it's better to use fixed-size arrays), you might want to store the sizes of both arrays in the struct
.
C/C++ 数组不在内存中存储它们自己的大小。因此,除非您想要offset
并values
拥有编译时定义的值(在这种情况下,最好使用固定大小的数组),否则您可能希望将两个数组的大小存储在struct
.
typedef struct tagswc {
short *offset;
char *values;
// EDIT: Changed int to size_t, thanks Chris Lutz!
size_t offset_count;
size_t values_count; // You don't need this one if values is a C string.
} swc;
DISCLAIMER: I might be wrong. For example, if all offset
s of all swc
instances have the same size, it would be better to store offset_count
as a global member, not as a member of the struct
. The same can be said about values
and values_count
. Also, if values
is a C string, you don't need to store its size, but beware of Schlemiel the painter-like problems.
免责声明:我可能是错的。例如,如果所有实例的所有offset
s 的swc
大小都相同,则最好将其存储offset_count
为全局成员,而不是struct
. 关于values
和也可以这样说values_count
。此外,如果values
是 C 字符串,则不需要存储其大小,但要注意Schlemiel 类似画家的问题。
回答by Luke
Since nobody has mentioned it yet, sometimes it is nice to grab this chunk of memory in one allocation so you only have to call free() on one thing:
由于还没有人提到它,有时在一次分配中获取这一块内存很好,因此您只需在一件事情上调用 free() :
swc* AllocSWC(int items)
{
int size = sizeof(swc); // for the struct itself
size += (items * sizeof(short)); // for the array of shorts
size += (items * sizeof(char)); // for the array of chars
swc* p = (swc*)malloc(size);
memset(p, 0, size);
p->offset = (short*)((char*)swc + sizeof(swc)); // array of shorts begins immediately after the struct
p->values = (char*)((char*)swc + sizeof(swc) + items * sizeof(short)); // array of chars begins immediately after the array of shorts
return p;
}
Of course this is a bit more difficult to read and maintain (especially if you dynamically resize the arrays after it is first allocated). Just an alternative method I've seen used in a number of places.
当然,这有点难以阅读和维护(尤其是在首次分配数组后动态调整数组大小时)。只是我在许多地方看到的另一种方法。