我很难用结构来记住C规则。基本上,我有一个像这样的结构:
typedef struct {
char* ptr;
int size;
} Xalloc_struct;
char* ptr
最多只能是一个字符
在我的程序中,我必须使用自己的函数将内存分配并释放到假磁盘(全局声明为char disk[100];
):
char disk[100];
void disk_init() {
for(int i = 0; i < 100; ++i) {
disk[i] = memory[i] = 0;
}
}
struct Xalloc_struct* Xalloc(int size) {
// error checking
// ...
// run an algorithm to get a char* ptr back to a part of the global disk
// array, where index i is the index where content at disk[i] starts
char* ptr = &disk[i];
struct Xalloc_struct *ret = malloc(sizeof(struct Xalloc_struct));
ret->size = size;
ret->ptr = malloc(sizeof(char));
ret->ptr = ptr;
return ret;
}
int Xfree(void* ptr) {
struct Xalloc_struct* p = (struct Xalloc_struct*) ptr;
int size = p->size;
int index = *(p->ptr);
// .. more stuff here that uses the index of where p->ptr points to
free(p->ptr);
free(p);
return 0;
}
int main() {
disk_init();
struct Xalloc_struct* x = Xalloc(5);
Xfree(x);
return 0;
}
当这个编译时,我会遇到很多错误:
error: invalid application of ‘sizeof’ to incomplete type ‘struct Xalloc_struct’
struct Xalloc_struct *ret = malloc(sizeof(struct Xalloc_struct));
^
error: dereferencing pointer to incomplete type
ret->size = size;
^
error: dereferencing pointer to incomplete type
free(x->ptr);
^
error: dereferencing pointer to incomplete type
int size = cast_ptr->size;
^
error: dereferencing pointer to incomplete type
int free_ptr = *(cast_ptr->ptr);
^
那么,我应该如何分配和解除分配这些结构?我如何修改/编辑它们包含的内容?
答案 0 :(得分:2)
第一个问题是Xalloc_struct
是一个类型,而不是结构的名称。你用这个声明了这个类型:
typedef struct {
char* ptr;
int size;
} Xalloc_struct;
typedef
的格式为typedef <type name or struct definition> <name of the type>
。因此,您将类型Xalloc_struct
声明为struct { char *ptr; int size; }
。
这意味着您可以像使用任何其他类型名称一样使用它:Xalloc_struct somevar = ...;
。
您是否使用名称声明了结构...
struct Xalloc_struct {
char* ptr;
int size;
};
然后就像你一样struct Xalloc_struct somevar = ...;
。
为数组分配内存时的经验法则(char *
是一个字符数组)是您分配sizeof(type) * number_of_items
。字符数组以空字节结束,因此对于它们,您还需要一个字符。
Xalloc_struct *ret = malloc(sizeof(Xalloc_struct));
ret->ptr = malloc(sizeof(char) * num_characters+1);
但如果您只存储一个字符,则不需要一个字符数组。只需存储一个角色。
typedef struct {
char letter;
int size;
} Xalloc_struct;
Xalloc_struct *ret = malloc(sizeof(Xalloc_struct));
ret->letter = 'q'; /* or whatever */
但我认为你真正在做的是存储指向disk
数组中某个点的指针。在这种情况下,你根本不需要malloc。您只需将指针存储为任何其他指针。
typedef struct {
char* ptr;
int size;
} Xalloc_struct;
Xalloc_struct *ret = malloc(sizeof(Xalloc_struct));
ret->ptr = &disk[i];
然后您可以使用ret->ptr[0]
读取该字符。
由于你没有分配ret->ptr
,所以不要释放它!这会导致崩溃,因为disk
位于堆栈内存中并且无法自由运行。如果它在堆内存(即malloc)中,它可能也会崩溃,因为它会尝试在分配的块中间释放。
void Xalloc_destroy(Xalloc_struct *xa) {
free(xa);
}
以下是我的表现。
#include <stdio.h>
#include <stdlib.h>
char disk[100] = {0};
typedef struct {
char *ptr;
int idx;
} Disk_Handle_T;
static Disk_Handle_T* Disk_Handle_New(char *disk, int idx) {
Disk_Handle_T *dh = malloc(sizeof(Disk_Handle_T));
dh->idx = idx;
dh->ptr = &disk[idx];
return dh;
}
static void Disk_Handle_Destroy( Disk_Handle_T *dh ) {
free(dh);
}
int main() {
Disk_Handle_T *dh = Disk_Handle_New(disk, 1);
printf("%c\n", dh->ptr[0]); /* null */
disk[1] = 'c';
printf("%c\n", dh->ptr[0]); /* c */
Disk_Handle_Destroy(dh);
}
答案 1 :(得分:1)
你试图完成的事情有点令人困惑,但从语法的角度来看,你的主要问题是将typedef视为一个正式的结构声明,而不是为你的Xalloc
函数提供索引信息,以及在ret->ptr
中已经有指针和存储的地方分配disk
。
首先,除非您指定指针,否则取消引用运算符'*'
将使用变量,而不是类型。 e.g。
Xalloc_struct *Xalloc (...)
不
Xalloc_struct* Xalloc (...)
为什么呢?为了避免使用指针 type (没有指针类型只是 type )声明某些内容的不正确外观,例如:
int* a, b, c;
上面的 b
和c
肯定不是指针类型,但是通过将'*'
附加到类型,看起来好像是在尝试声明变量int*
(不正确)。
int *a, b, c;
让你更明确地想要在a
和两个整数b
和c
中声明一个指向int 的指针。
接下来,在Xfree
中,您可以(但通常不希望)将指针类型指定为int
(存储大小问题等)(例如int index = *(p->ptr);
)如果你需要一个指针的引用,使用指针。如果你想要指针本身的地址,请确保你使用的类型足够大,以适应硬件上的指针大小。
为什么要为ret->ptr = malloc(sizeof(char));
分配存储空间?您已在char disk[100];
中拥有存储空间您无法从分配中获益。只需将disk
中元素的地址分配给ptr
(指针可以保存指针而无需进一步分配)如果您打算使用内存,则只需要为ret->ptr
分配存储空间分配,例如将字符串或多个字符复制到分配给ret->ptr
的内存块。 ret->ptr
可以在data
中存储元素的地址,而无需进一步分配。 (它不清楚你到底想要什么)
您可以自由使用typedef
,实际上这是一种很好的做法,但是当您指定typedef
时,它不等同于,也不能用作命名结构。这就是你的不完整类型问题出现的地方。
总而言之,您似乎尝试执行类似以下操作:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char* ptr;
int size;
} Xalloc_struct;
char disk[100] = "";
Xalloc_struct *Xalloc (int size, int i) {
char *ptr = &disk[i];
Xalloc_struct *ret = malloc (sizeof *ret);
ret->size = size;
// ret->ptr = malloc (sizeof *(ret->ptr)); /* you have a pointer */
ret->ptr = ptr;
return ret;
}
int Xfree (void *ptr) {
Xalloc_struct *p = (Xalloc_struct *) ptr;
// int size = p->size; /* unused */
// int index = *(p->ptr); /* what is this ?? */
// .. more stuff here that uses the index of where p->ptr points to
// free (p->ptr);
free (p);
return 0;
}
int main (void) {
int i = 0;
Xalloc_struct *x = Xalloc (5, i++);
Xfree(x);
return 0;
}
查看typedef的使用方式的不同,如果您有任何疑问,请告诉我。