所以,我正在创建一个目前需要大量内存的结构。我希望将来减少它,但就目前而言,它就是它。因此,我需要在堆上分配一些元素,因为如果将它们放在堆栈上,我会得到堆栈溢出。是的,我增加了堆栈大小,但在目标平台上我只有这么多。
在这种情况下,在堆上分配每个结构元素,或者将一些结构元素放在堆栈上以及堆上的大块内容是否“更好”?例如:
typedef struct my_structure_s{
int bounds[2];
int num_values;
int* values; //needs to be very large
} my_structure_t;
Vs的:
typedef struct my_structure_s{
int* bounds;
int* num_values;
int* values;
} my_structure_t;
我知道'更好'在很大程度上是主观的,很可能在这里引发骚乱。那么,这两个例子的优点和缺点是什么?你平常都做什么?为什么呢?
另外,请原谅_s,_t的东西......我知道你们中的一些人可能会觉得它的味道不好,但这是将要集成到的遗留代码库的惯例。
谢谢大家!
答案 0 :(得分:3)
最好将简单成员保留为直接值,并仅分配数组。使用额外的两个指针只会减慢访问速度,但没有任何好处。
如果你有C99或C11,另外一个选择是使用灵活的阵列成员(FAM)。
您使用符号来定义您的结构:
typedef struct my_structure_s
{
int bounds[2];
int num_values;
int values[];
} my_structure_t;
您可以在一次操作中为结构和values
中的N元素数组分配足够的内存,使用:
my_structure_t *np = malloc(sizeof(*np) + N * sizeof(np->values[0]));
这意味着你只需要释放一块内存来释放。
您可以找到对' struct hack'的引用。如果你搜索。这种表示法实际上是结构黑客的标准化形式。
在评论中,讨论仍在继续:
这是一种有趣的方法;但是,我不能保证我会有C99。
如果需要,您可以使用' struct hack'代码的版本,如下所示:
typedef struct my_structure_s
{
int bounds[2];
int num_values;
int values[1];
} my_structure_t;
其余代码保持不变。这比FAM解决方案和isn't strictly supported by the standard使用更多的内存(多出4-8个字节),但它在C99标准之前被广泛使用,因此编译器不太可能使这些代码无效。
好的,但是怎么样:
typedef struct my_structure_s { int bounds[2]; int num_values; int values[MAX_SIZE]; } my_structure_t;
然后:
my_structure_t *the_structure = malloc(sizeof(my_structure_t));
这也会给我一个固定的块大小吗? (除此之外,我的块大小将比它需要的大,在某些情况下,因为我不会总是达到MAX_SIZE)。
如果平均没有太多浪费的空间,那么结构中的固定大小的数组仍然更简单。此外,这意味着如果MAX_SIZE不是太大,您可以在堆栈或堆上进行分配,而FAM方法则要求动态(堆)分配。问题在于浪费的空间是否足够问题,以及如果MAX_SIZE毕竟不够大,你会怎么做。否则,这是最简单的方法;我只是假设你已经排除了它。
请注意,建议的解决方案中的每一个都避免了问题中选项2中建议的bounds
和num_values
指针。
答案 1 :(得分:0)
做第一个。它更简单,更不容易出错(你必须记住在第二个中分配和释放更多东西)
顺便说一句 - 不是第一个例子不会将num_values放在堆栈上。无论你在哪里分配结构,堆栈,静态堆
,IT都会去