我想动态分配一个C结构:
typedef struct {
short *offset;
char *values;
} swc;
'offset'和'values'都应该是数组,但它们的大小在运行时才会被识别。
如何为我的struct和struct的数组动态分配内存?
答案 0 :(得分:18)
swc *a = (swc*)malloc(sizeof(swc));
a->offset = (short*)malloc(sizeof(short)*n);
a->values = (char*)malloc(sizeof(char)*n);
其中n =每个数组中的项数,a是新分配的数据结构的地址。在free()之前不要忘记free()偏移量和值。
答案 1 :(得分:9)
在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);
}
在C ++中:
try
{
swc *s = new swc;
s->offset = new short[number_of_offset_elements];
s->values = new char[number_of_value_elements];
}
catch(...)
{
...
}
请注意,在C ++中,最好使用向量而不是动态分配的缓冲区:
struct swc
{
std::vector<short> offset;
std::vector<char> values;
};
swc *a = new swc;
问题:值应该是单个字符数组还是字符串数组?这会改变一些事情。
修改强>
我想的越多,我对C ++答案的满意度就越低; 正确在C ++中做这种事情的方式(假设需要动态分配缓冲区而不是向量,你可能不需要)是执行内存分配for offset和values作为struct类型中构造函数的一部分,并且在构造实例被销毁时(由delete
或超出范围),析构函数释放这些元素。
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
}
答案 2 :(得分:4)
你必须分开做。首先分配结构,然后分配数组的内存。
在C:
swc *pSwc = malloc(sizeof(swc));
pSwc->offset = malloc(sizeof(short)*offsetArrayLength);
pSwc->values = malloc(valuesArrayLength);
在C ++中,你不应该做那样的事情。
答案 3 :(得分:4)
在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);
}
在C ++中
struct swc
{
std::vector<short> offset;
std::vector<char> values;
swc(unsigned int size)
:offset(size)
,values(size)
{}
};
答案 4 :(得分:3)
您需要一个功能才能执行此操作。 像(我的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);
语法可能有点偏,但这通常是你需要的。如果你正在使用C ++,那么你可能想要一个带有构造函数的类,而不是makeStruct,而是做一些非常相似的东西。
答案 5 :(得分:3)
在这里添加许多正确答案的一件事是:你可以 malloc
一个超大的结构,以容纳最后一个成员中的可变大小的数组。
struct foo {
short* offset;
char values[0]
};
以后
struct *foo foo1 = malloc(sizeof(struct foo)+30); // takes advantage of sizeof(char)==1
为values
数组中的30个对象腾出空间。你仍然需要做
foo1->offsets = malloc(30*sizeof(short));
如果您希望它们使用相同大小的数组。
我通常不会这样做(维护噩梦,如果结构需要扩展),但它是套件中的工具。
[c代码。您需要在c ++中投射malloc
(或更好地使用new
和RAII习语)
答案 6 :(得分:2)
swc* a = malloc(sizeof(*a));
a->offset = calloc(n, sizeof(*(a->offset)));
a->values = calloc(n, sizeof(*(a->values)));
你不应该在c ++中将void *转换为c ++,你必须!
答案 7 :(得分:1)
使用malloc函数或calloc动态分配内存。 并在谷歌上搜索以获得示例。
The calloc function initializes allocated memory to zero.
答案 8 :(得分:1)
大部分答案都是正确的。我想补充一些你没有明确要求的东西,但也可能很重要。
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;
免责声明:我可能错了。例如,如果所有offset
实例中的所有swc
具有相同的大小,则最好将offset_count
存储为全局成员,而不是{{1}的成员}。 struct
和values
也是如此。另外,如果values_count
是C字符串,则不需要存储其大小,但要注意Schlemiel the painter - 类似问题。
答案 9 :(得分:1)
由于还没有人提到它,有时在一个分配中抓住这块内存是很好的,所以你只需要在一件事上调用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;
}
当然这有点难以阅读和维护(特别是如果你在首次分配数组后动态调整数组大小)。只是我在很多地方看到的另一种方法。
答案 10 :(得分:0)
您希望使用malloc来分配内存,也可能使用sizeof()来分配正确的空间量。
类似的东西:
structVariable = (*swc) malloc(sizeof(swc));
应该做的伎俩。
答案 11 :(得分:0)
除了上述内容之外,我还想添加释放分配的内存,如下所示。
typedef struct {
short *offset;
char *values;
} swc;
swc* createStructure(int Count1, int Count2) {
swc *s1 = new swc();
s1->offset = new short[Count1];
s1->values = new char[Count2];
return s1;
}
int _tmain(int argc, _TCHAR* argv[])
{
swc *mystruct;
mystruct = createStructure(11, 11);
delete[] mystruct->offset;
delete[] mystruct->values;
delete mystruct;
return 0;
}
答案 12 :(得分:0)
**如果** 您不会调整数组的大小,那么您只需拨打一次malloc()
即可离开。
swc *new_swc (int m, int n) {
swc *p;
p = malloc (sizeof (*p) + m * sizeof (p->offset[0]) + n * sizeof (p->values[0]);
p->offset = (short *) &p[1];
p->values = (char *) &p->offset[m];
return p;
}
然后,您只需拨打free()
即可将其释放。
(一般情况下,需要考虑对齐因素,但对于一系列短路后跟一组字符,你会没事的。)