动态分配C结构?

我想动态分配一个C结构:

typedef struct { short *offset; char *values; } swc; 

‘offset’和’values’都应该是数组,但是它们的大小在运行时才会被识别。

如何为我的struct和struct的数组动态分配内存?

 swc *a = (swc*)malloc(sizeof(swc)); a->offset = (short*)malloc(sizeof(short)*n); a->values = (char*)malloc(sizeof(char)*n); 

其中n =每个数组中的项数,a是新分配的数据结构的地址。 在free()之前不要忘记free()偏移量和值。

在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 offset; std::vector values; }; swc *a = new swc; 

问题:值应该是单个字符数组还是字符串数组? 这会改变一些事情。

编辑

我想的越多,我对C ++答案的满意度就越低; 在C ++中执行此类操作的正确方法(假设您需要动态分配的缓冲区而不是向量,您可能不需要)是为结构类型中的构造函数执行偏移量和值的内存分配,并且析构函数在结构实例被销毁时(通过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 } 

你必须单独做。 首先分配结构,然后分配数组的内存。

在C:

 swc *pSwc = malloc(sizeof(swc)); pSwc->offset = malloc(sizeof(short)*offsetArrayLength); pSwc->values = malloc(valuesArrayLength); 

在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); } 

在C ++中

 struct swc { std::vector offset; std::vector values; swc(unsigned int size) :offset(size) ,values(size) {} }; 

您将需要一个function来执行此操作。 像(我的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,而是做一些非常相似的东西。

在这里添加许多正确答案的一件事是:你可以 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习语)

 swc* a = malloc(sizeof(*a)); a->offset = calloc(n, sizeof(*(a->offset))); a->values = calloc(n, sizeof(*(a->values))); 

你不应该在c ++中使用void *来构建void *!

使用malloc函数或calloc动态分配内存。 并在谷歌搜索它以获取示例。

 The calloc function initializes allocated memory to zero. 

既然没人提到它,有时在一个分配中抓住这块内存是很好的,所以你只需要在一件事上调用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; } 

当然,这有点难以阅读和维护(特别是如果您在首次分配数组后动态调整数组大小)。 只是我见过的一种替代方法在很多地方使用过。

大多数答案都是正确的。 我想补充一些你没有明确要求但可能也很重要的东西。

C / C ++数组不会在内存中存储自己的大小 。 因此,除非您希望offsetvalues具有编译时定义的值(并且在这种情况下,最好使用固定大小的数组),您可能希望将两个数组的大小存储在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; 

免责声明 :我可能错了。 例如,如果所有swc实例的所有offset s具有相同的大小,则最好将offset_count存储为全局成员,而不是struct的成员。 关于valuesvalues_count也可以values_count 。 此外,如果values是C字符串,则不需要存储其大小,但要注意Schlemiel类似画家的问题。

您希望使用malloc来分配内存,也可能使用sizeof()来分配正确的空间量。

就像是:
structVariable = (*swc) malloc(sizeof(swc));

应该做的伎俩。

除了上面的内容,我想添加释放分配的内存,如下所示。

  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; } 

**如果**你不会调整数组的大小,那么你可以通过一次调用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()free()它。

(一般来说,需要考虑对齐因素,但对于一系列短路后跟一组字符,你会没事的。)