繁体   English   中英

C中的结构和动态内存分配?

[英]Structs and dynamic memory allocation in C?

有人可以帮我用 C 编写程序以创建一个无限循环数组吗?

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int size;
    int *a;
} array;

array* unbounded_create() {
    array *x;
    x->size = 64;
    x = (array*)malloc(x->size*sizeof(array));
    if(x==NULL) {
        fprintf(stderr,"Could not allocate memory.\n");
        abort();
    }
    return x;
}

void unbounded_destroy(array *a) {
    free(a->a);
} 

void unbounded_double(array *a) {
    a = (array*)malloc(2*sizeof(array));
    a->size *= 2;
}

void unbounded_set(array *a, int i, int value) {
    while(i>a->size) {
        unbounded_double(a);
    }
    a->a[i] = value;
}

int unbounded_get(array *a, int i){
    while(i>a->size) {
        unbounded_double(a);
    }
    return a->a[i];
}

int main() {
    int i;
    array *A = unbounded_create();
    for(i=0;i<1000;i++) 
        unbounded_set(A,i,i);
    for(i=0;i<1000;i++)
        printf("%d", unbounded_get(A,i));
    puts("");
    unbounded_destroy(A);
    return 0;
}

这是我的代码,但编译器发送分段错误。 有人可以解释为什么会发生这种情况吗?

看这个:

array *x;
x->size = 64;  // Here you dereference x but x is uninitialized
x = (array*)malloc(x->size*sizeof(array));  // Here you assign to x

所以你在x未初始化时使用它。 这可能会导致段错误。

...但编译器发送分段错误

Nitpick:不,编译器不会发送段错误。 段错误发生在运行时。 不是在编译时。

进一步 - 这:

void unbounded_double(array *a) {
    a = (array*)malloc(2*sizeof(array));
    a->size *= 2;
}

不好。 您不能在调用者中更改a 你想要这样的东西:

void unbounded_double(array **a) {  // Pointer to pointer
    *a = malloc(2*sizeof(array));
    (*a)->size *= 2;
}

您似乎忽略了一个事实,即您需要为两件事分配内存:

  • 结构本身
  • 结构包含的数组。

查看unbounded_create

array *x;
x->size = 64;
x = (array*)malloc(x->size*sizeof(array));

在为x赋值之前取消引用它。 这会调用未定义的行为,在这种情况下会导致崩溃。

然后您将内存分配给x ,但不是适当的数量,并且您永远不会为a成员分配内存。 结构需要sizeof(array)字节, sizeof(array)需要x->size*sizeof(int)字节。

现在看unbounded_double

void unbounded_double(array *a) {
    a = (array*)malloc(2*sizeof(array));
    a->size *= 2;
}

您通过用新分配的内存覆盖它来丢弃先前分配给a的内存,并且您没有分配正确的数量。 但是,由于结构体指针是按值传递的,因此更改不会反映在函数外部,因此所做的只是泄漏内存。

您不需要为array实例分配空间,但您确实需要在a成员上使用realloc来扩展其大小并保留以前存储在那里的内容。

然后在unbounded_destroy

void unbounded_destroy(array *a) {
    free(a->a);
} 

您从未为a->a分配空间,而是尝试释放它,并且没有为a释放空间。 修复数组创建后,您需要释放两者。

进行上述更正后,您的代码应如下所示:

array* unbounded_create() {
    array *x;
    x = malloc(sizeof(array));   // don't cast the return value of malloc
    if(x==NULL) {
        fprintf(stderr,"Could not allocate memory.\n");
        abort();
    }

    x->size = 64;
    x->a = malloc(x->size*sizeof(int));
    if(x->a==NULL) {
        fprintf(stderr,"Could not allocate memory.\n");
        abort();
    }
    return x;
}

void unbounded_destroy(array *a) {
    free(a->a);
    free(a);
} 

void unbounded_double(array *a) {
    a->a = realloc(2*a->size*sizeof(int));
    if(a->a==NULL) {
        fprintf(stderr,"Could not allocate memory.\n");
        abort();
    }
    a->size *= 2;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM