[英]Memory allocation to struct in pure C
我有一个结构,它表示我的数据元素
struct myElement
{
int field1;
int field2;
int field3;
};
另一个结构,包含此元素的数组和一些其他数据
struct myArray
{
struct myElement *elements;
int someData;
};
我需要像这样的数组的数组
struct myArray *myMatrix;
但是我在内存分配上有问题。 myArray中的元素数量可以不同,myMatrix中的元素数量也可以不同,因此我需要动态分配内存。 在这种情况下,分配和释放内存的正确方法是什么?
这是一个小示例,说明如何在struct myArray
分配( malloc
)和释放( free
)动态struct myElement
数组。 还要注意,您将需要跟踪数组的大小,因此我添加了size_t elements_len;
struct myArray
(请使用camelCase和下划线的组合-我在C语言中使用下划线,但不想修改您的标识符):
#include <stdlib.h>
struct myElement
{
int field1;
int field2;
int field3;
};
struct myArray
{
struct myElement *elements;
size_t elements_len;
int someData;
};
void allocate_elements(struct myArray *m, size_t length)
{
m->elements = malloc(length * sizeof( *m->elements) );
m->elements_len = length;
}
void free_elements(struct myArray *m)
{
free(m->elements);
m->elements = NULL; /* point to NULL to signify no array allocated */
m->elements_len = 0; /* length of 0 also signifies no elements/no array */
}
int main(void)
{
struct myArray ma;
allocate_elements(&ma, 5);
free_elements(&ma);
return 0;
}
应用类似的逻辑以获取struct myArray
的动态数组。 你会malloc
足够的内存为X量struct myArray
S,则for
每个struct myArray
数组中元素,你会打电话allocate_elements
。 完成后,遍历数组中的每个元素,并调用free_elements
。
int num_elements = 1234; // whatever
struct myArray *myMatrix;
myMatrix = malloc (num_elements * sizeof (*myMatrix));
if (!myMatrix)
// error
// subsequent use of myMatrix is just like it had been statically dimensioned:
myMatrix [0].someData = 343;
myMatrix [1].someData = 323;
使用malloc
分配内存:
myMatrix = malloc(sizeof(myArray)*dim1);
for (int i = 0; i < dim1; i++)
myMatrix[i].elements = malloc(sizeof(myElement)*dim2);
完成使用后,以类似方式使用free
释放内存。
struct myArray *myMatrix = malloc(Nentries * sizeof(*myMatrix));
if (myMatrix != 0)
{
for (int i = 0; i < Nentries; i++)
{
myMatrix[i].elements = malloc(Nelements[i] * sizeof(myElement));
if (myMatrix[i].elements != 0)
{
for (int j = 0; j < Nelements[i]; j++)
{
myElement *e = &myMatrix[i].elements[j];
e->field1 = 0;
e->field2 = 1;
e->field3 = 2;
}
myMatrix[i].someData = 37;
}
}
}
我假设Nentries
表示矩阵中有多少个元素,而数组Nelements
每个元素Nelements
表示矩阵的相应元素中有多少个元素。 该代码测试内存分配是否成功,但不会对分配失败做出反应。
像这样的事情应该可以工作,尽管对于这么多单独的分配来说,这不是一个很好的解决方案,而进一步下去则是一个更好的解决方案。 我试图使变量名描述它们的含义。
int arrayOfSubArrayLengths={9,5,10,50,...};
int lengthOfMyMatrix=something;
myMatrix= (myArray*) malloc( sizeof(myArray) * lengthOfMyMatrix);
for(int i=0; i<lengthOfMyMatrix; ++i)
{
myMatrix[i].elements=new myElement[arrayOfSubArrayLengths];
myMatrix[i].someData=whatever;
}
删除:
for(int i=0; i<lengthOfMyMatrix; ++i)
{
free( myMatrix[i].elements );
}
free( myMatrix );
但是,正如我所说的,分配这么多不是一个好的解决方案。 这可能会导致一些严重的内存碎片,具体取决于lengthOfMyMatrix的大小。 同样,对分配器的如此多次调用可能会使速度变慢,这再次取决于lengthOfMyMatrix的大小。 这是一个更好的解决方案:
int arrayOfSubArrayLengths={9,5,10,50,...};
int lengthOfMyMatrix=something;
int sumOfSubArrayLengths=someNumber;
myArray* fullArray=(myElement*) malloc( sizeof(myElement) * sumOfSubArrayLengths);
myMatrix= (myArray*) malloc( sizeof(myArray) * lengthOfMyMatrix);
int runningSum=0;
for(int i=0; i<lengthOfMyMatrix; ++i)
{
myMatrix[i].elements = &fullArray[runningSum];
runningSum += arrayOfSubArrayLengths[i];
myMatrix[i].someData = whatever;
}
删除:
free( fullArray );
free( myMatrix );
以这种方式,无论长度如何,都只有两次调用分配器。 因此,存在更多的内存碎片和更少的分配开销时间。 第二种方法的缺点是,如果您不小心进行边界检查,那么很容易在不知道的情况下破坏数组中的数据,因为内存“属于”您,因此操作系统不会因访问冲突而踢您。
您需要使用malloc
和free
函数来动态分配和释放内存。 请参考以下内容。
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct myElement {
int field1;
int field2;
int field3;
};
struct myArray {
struct myElement *elements;
int someData;
};
struct myArray *myMatrix = NULL;
int n_myarray = 0;
int n_elements = 0;
int i, j;
printf("How many myArray's do you want? ");
scanf("%d", &n_myarray);
printf("How many elements do you want in each array? ");
scanf("%d", &n_elements);
/* memory allocation starts here */
if ((myMatrix = (struct myArray *) malloc((int)sizeof(struct myArray) * n_myarray)) == NULL) {
printf("ERROR: unable to allocate array\n");
return 1;
}
for (i=0 ; i<n_myarray ; i++) {
if ((myMatrix[i].elements = (struct myElement *) malloc((int)sizeof(struct myElement) * n_elements)) == NULL) {
printf("ERROR: unable to allocate array elements\n");
free(myMatrix);
return 1;
}
/* initialization of other members of struct myArray goes here */
myMatrix[i].someData = 123;
/* initialization of members of struct myElement goes here */
for (j=0 ; j<n_elements ; j++) {
myMatrix[i].elements[j].field1 = 123;
myMatrix[i].elements[j].field2 = 123;
myMatrix[i].elements[j].field3 = 123;
}
}
/* do your calculations here */
/* I'm printing the values */
for (i=0 ; i<n_myarray ; i++) {
printf("myMatrix[%d].someData : %d \n", i, myMatrix[i].someData);
for (j=0 ; j<n_elements ; j++) {
printf("myMatrix[%d].elements[%d].field1 : %d \n", i, j, myMatrix[i].elements[j].field1);
printf("myMatrix[%d].elements[%d].field2 : %d \n", i, j, myMatrix[i].elements[j].field2);
printf("myMatrix[%d].elements[%d].field3 : %d \n", i, j, myMatrix[i].elements[j].field3);
}
}
/* memory deallocation (free) starts here */
for (i=0 ; i<n_myarray ; i++) {
free(myMatrix[i].elements);
}
free(myMatrix);
return 0;
}
> ./a.out
How many myArray's do you want? 2
How many elements do you want in each array? 5
myMatrix[0].someData : 123
myMatrix[0].elements[0].field1 : 123
myMatrix[0].elements[0].field2 : 123
myMatrix[0].elements[0].field3 : 123
myMatrix[0].elements[1].field1 : 123
myMatrix[0].elements[1].field2 : 123
myMatrix[0].elements[1].field3 : 123
myMatrix[0].elements[2].field1 : 123
myMatrix[0].elements[2].field2 : 123
myMatrix[0].elements[2].field3 : 123
myMatrix[0].elements[3].field1 : 123
myMatrix[0].elements[3].field2 : 123
myMatrix[0].elements[3].field3 : 123
myMatrix[0].elements[4].field1 : 123
myMatrix[0].elements[4].field2 : 123
myMatrix[0].elements[4].field3 : 123
myMatrix[1].someData : 123
myMatrix[1].elements[0].field1 : 123
myMatrix[1].elements[0].field2 : 123
myMatrix[1].elements[0].field3 : 123
myMatrix[1].elements[1].field1 : 123
myMatrix[1].elements[1].field2 : 123
myMatrix[1].elements[1].field3 : 123
myMatrix[1].elements[2].field1 : 123
myMatrix[1].elements[2].field2 : 123
myMatrix[1].elements[2].field3 : 123
myMatrix[1].elements[3].field1 : 123
myMatrix[1].elements[3].field2 : 123
myMatrix[1].elements[3].field3 : 123
myMatrix[1].elements[4].field1 : 123
myMatrix[1].elements[4].field2 : 123
myMatrix[1].elements[4].field3 : 123
>
请确保以下内容:
malloc
应该有一个free
malloc
分配的内存之前,必须检查malloc
是否成功分配了您请求的内存块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.