在我开始之前,我应该说这与直接问题无关,但出于好奇和我无法找到与我之后完全相关的事情。我现在正在教自己C,我有其他几种语言的经验,所以除了如何执行某些事情之外,它没什么新鲜的。
我想在C中做一个挑战,比如构建一个可以根据需要增长一定数量的Stack,我选择使用一个结构:
#define INITIAL_STACK_SIZE 10
typedef struct Stack {
int max_size;
int cur_top;
int *elements;
} Stack;
我将元素保留为空点,以便可以根据需要进行扩展,这使得构建堆栈的函数就像:
Stack *Stack_make() {
Stack *stack = malloc(sizeof(Stack)); // This is ultimately where I become confused
stack->max_size = INITIAL_STACK_SIZE;
stack->cur_top = -1;
stack->elements = malloc(sizeof(int) * INITIAL_STACK_SIZE);
return stack;
}
正如我所指出的,我的困惑在于结构的malloc。我知道C在内存中对齐struct数据元素,所以我很好奇如果将元素指针稍后或次要地分配给struct本身,它将如何做到这一点。这是不好的做法吗?有更好的方法吗?
为了完整性,这就是我扩展堆栈的原因:
// Relevant bits only
int new_size = stack->max_size + INITIAL_STACK_SIZE;
int *elements = malloc(sizeof(int) * new_size));
if (elements != NULL) {
memcpy(elements, stack->elements, sizeof(int) * stack->max_size);
free(stack->elements);
stack->elements = elements;
}
我知道这不是#34;代码审查的最佳位置"但是,如果你有改进的建议,那将是什么不值得赞赏。 实际问题:有没有更好的方法在C中执行此操作,是否有任何陷阱我会掩饰?
答案 0 :(得分:2)
我知道C在内存中对齐struct数据元素,所以我很好奇如果将元素指针稍后或次要地分配给结构本身,它将如何做到这一点。
指针将与结构的其余部分位于相同的连续内存中,但指针指向的malloc
内存将由malloc
放置。realloc
。 (毕竟,你可以有多个结构,指向同一个内存;显然,它不能与所有结构对齐。)
这是不好的做法吗?
这取决于"这个"是。如果"这"在结构中有一个指针来动态分配内存,然后没有,这不是坏习惯。
那就是说,你的特定算法并不好,因为它涉及每次复制所有内容。
有更好的方法吗?
是的,realloc
。
int new_size = stack->max_size + INITIAL_STACK_SIZE;
int *elements = realloc(stack->elements, sizeof(int) * new_size);
if(elements != NULL) {
stack->elements = elements;
}
,如果可能,将扩展先前为该指针分配的内存。如果那是不可能的,那么它将为你移动内存块(并解除分配使用的内容)。返回值是指向内存的指针,可以是相同的指针,也可以是新指针。
所以你的代码(或至少你共享的那个代码)变成了:
{{1}}
仅供参考,flexible array members(在C99中)具有可变长度,但是为结构本身分配了included in the memory。它们不适合您的需求,但考虑到有关内存对齐的问题,您可能有兴趣了解它们。