我想知道为具有多个指针的结构分配内存的最佳策略是什么。
像这样:
&&
然后我可以使用很多分配,如下所示:
struct Test{
long unsigned int size;
double *A;
int *B;
double *C;
};
或者我可以使用单个分配,例如:
struct Test *alloc_test(long unsigned int size){
struct Test *ans = (struct Test*)malloc(sizeof(struct Test));
if(ans == NULL){
return NULL;
}
ans->size = size;
ans->A = (double *)malloc(sizeof(double)*size);
if(ans->A == NULL){
free(ans);
return NULL;
}
ans->B = (int *)malloc(sizeof(int)*size);
if(ans->B == NULL){
free(ans->A);
free(ans);
return NULL;
}
ans->C = (double *)malloc(sizeof(double)*size);
if(ans->C == NULL){
free(ans->A);
free(ans->B);
free(ans);
return NULL;
}
return ans;
}
这可能是因为这个对象不应该被重新分配。在这种情况下,有谁知道每个人的优势?
答案 0 :(得分:3)
两者都是可能的,你选择哪一个是你的自由。但是,您应该遵守alignment限制(可能使用alignas
alignof
和<stdalign.h>
作为单一分配变体
另请阅读flexible array members,在特定情况下,只允许一个malloc
一个数组成员。
请注意,对malloc
的每次调用都有其开销(在内存中,可能会为内部管理消耗额外的一两个字,并且及时;一个典型的malloc
在我的内存上花费不到一微秒桌面)。
对于长效计划,例如您可能也关心fragmentation的服务器(对于大多数短期应用程序而言不是问题)
第二种方法(单malloc
)可能稍微更友好cache。大多数情况下,你不会在意。
BTW(由chux评论)
ans->A = ans + sizeof(struct Test);
是错误的,因为指针算法以指向类型为单位发生。你可能想要
ans->A = ((char*)ans)+sizeof(struct Test);
实际上你应该更仔细地计算mem_size
(在其中同时使用alignof
,或者假设alignof(long unsigned int) >= alignof(double)
等等)然后更喜欢
char* ad = malloc(mem_size);
if (!ad) return NULL;
ans = ad;
ans->A = ad + sizeof(struct Test);
mem_size
的精确计算(需要一些条件和使用alignof
)和真实代码留作练习(我在这里解释它太蹩脚了)。
答案 1 :(得分:3)
在Plan A中,您可以获得内存防护,特定于体系结构的内存对齐,以及重新分配的能力。当然,人们可以稍微重构一下,以便错误处理不会分散 - 但这是个人风格的问题。
在B计划中,你失去了所有自动化的东西 - 你必须要照顾它。然后可能会很难阅读。
根据您的分配器,您可能更容易找到多个较小的内存块而不是一个兆块。所以,从战略角度来说,你必须做出自己的决定 - 如果你有自己的分配器。
答案 2 :(得分:1)
让我告诉你如何以更清洁的方式处理第一种情况的错误:
struct Test *alloc_test(long unsigned int size)
{
struct Test *ans = malloc(sizeof(struct Test));
if(ans == NULL)
{
return NULL;
}
ans->size = size;
ans->A = malloc(sizeof(ans->A) * size);
ans->B = malloc(sizeof(ans->B) * size);
ans->C = malloc(sizeof(ans->C) * size);
if(ans->A == NULL || ans->B == NULL || ans->C == NULL)
{
free(ans->A);
free(ans->B);
free(ans->C);
free(ans);
return NULL;
}
return ans;
}
答案 3 :(得分:0)
您可能不需要使用多次调用malloc()
或完全处理对齐。
如果所有动态分配的数组总是具有相同数量的元素,请使用包含实际值的struct
,并创建struct
的数组:
typedef struct data
{
double A;
double B;
int C;
};
分配:
struct data *dataPtr = malloc( size * sizeof( *dataPtr ) );
取消分配:
free( dataPtr );
简单易懂。
如果您需要随身携带数据,请使用struct
灵活数组struct data
:
typedef struct test
{
unsigned long size;
struct data[];
}
分配:
struct test *testPtr = malloc( sizeof( *testPtr ) + size * sizeof( testPtr->data ) );
testPtr ->size = size;
取消分配:
free( testPtr );