为什么一种分配内存的方法与另一种方法相比有效?

时间:2017-07-04 16:44:09

标签: c malloc realloc

如果我打算创建一个动态大小的结构数组。有人可以向我解释一个分配内存来调整数组大小的方法是如何工作的;将x个元素添加到数组后失败的那个?

以下方法使用malloc()(错误地)。有人可以解释如何正确地为阵列分配内存吗?

struct some_struct{...data members...}*collection = NULL;
    int total_elements;
    int space_allocated; // the number of elements allocated to the array

    void resize_array(){
        if(total_elements == space_allocated) {
            if(space_allocated == 0)
                space_allocated =2;
            else
                space_allocated *= 2;
            //where collection is a pointer to a struct
            collection = malloc(space_allocated * sizeof(struct some_struct));

            if(collection == NULL){
                fprintf(stderr,"NO MEMORY ALLOCATED");
                exit(EXIT_FAILURE);
            }
        }
    }

与使用realloc()正确动态分配数组内存的另一种方法相比。用于保存内存的void *类型变量的意义是什么?

    void resize_array(){

        if(total_elements == space_allocated){
            if(space_allocated == 0)
                space_allocated = 2;
            else
                space_allocated *= 2;
                //why is a variable of type void allowed? What does that mean?
                void* tmp = realloc(collection, ((num_allocated)*
                sizeof(struct some_struct)));
                if(!_tmp){
                    fprintf(stderr,"NO MEMORY ALLOCATED");
                    exit(EXIT_FAILURE);
                }
                //what is the significance of the pointer cast?
                collection = (some_struct*) _tmp;
        }
    }

2 个答案:

答案 0 :(得分:0)

您应该使用malloc分配第一个初始化,并使用realloc调整其大小。

当您以第一种方式再次malloc(完全无意义)时,系统会分配一个新的内存空间并返回该地址。现在你做了一个很好的内存泄漏。

第二种方式看似合乎逻辑,请记住,在某些编译器旁边,可以使用realloc代替malloc(其中重新分配内存为NULL),但您可以先执行用malloc初始化并忽略它们的善意。

reallocmalloc都返回void*,但最后它们都是字节(char)。由于C经过很好的处理,您可能会也可能不会将返回类型强制转换为类型(指针)。但在c ++中,它是差异。

答案 1 :(得分:0)

您可以使用void *类型,但我更喜欢使用正确的类型

struct some_struct *tmp = realloc(collection, num_allocated * sizeof *tmp);

临时变量用于避免错误路径中的内存泄漏:

if (!tmp) {
    perror("realloc()");
    free(collection);
    goto err;
}

collection = tmp;

realloc()初始化为collection时,您始终可以使用NULL。但是您应该验证num_allocated * sizeof *tmp不会溢出。