[英]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.