混淆了结构和结构指针
Confused between structures and strucutre pointers
我想知道之间的区别
struct file_operations {
} a;
和
struct file_operations {
} *a;
它们在内存中是如何分配的?在第一种情况下,编译器如何知道"a"的内存位置?它来自符号表吗?如果是,如何找到地址到符号表(或任何其他表(?
在第二种情况下,我假设内存地址存储在一个大小为32位的变量中,这个变量的位置(第二个代码中"a"的地址(是如何计算出来的?
在第一种情况下,在内存中分配结构的实例,分配的字节数等于sizeof(a)
返回的值。
在第二种情况下,分配指针,分配的字节数等于指针的大小,即sizeof(void *)
。
正如您可能猜测的那样,第二种情况不允许您访问结构的字段,因为指针指向的内存是无效的,直到您从堆中请求足够的内存,或者直到您使其指向像第一个示例中那样的实例。
假设我们有以下结构
struct Data {
int quantity;
double value;
char name[100];
};
如果您执行以下
struct Data data;
然后分配struct Data
的实例,您可以立即访问它的字段,例如
data.quantity = 1;
data.value = 3.0;
strcpy(data.name, "My Name Is ...");
如果你声明一个指针,比如
struct Data *pointer;
然后,在指针指向struct Data
的有效实例之前,您不能访问字段,否则将发生未定义的行为,您可以通过获取上面已经初始化的struct Data data;
的地址来创建这样的实例,就像这个
pointer = &data;
指针对象的生存期限制了指针的有效期,一旦超出声明data
的范围,指针将指向垃圾,因为data
将被释放。
另一种使指针有效的方法是使用malloc()
,即通过从系统堆请求内存,这是通过请求sizeof(struct Data)
字节来完成的,就像这里的1
pointer = malloc(sizeof(struct Data));
之后,您首先检查内存是否已分配,当出现问题时,malloc()
保证返回一个特殊的poitner NULL
,它是一个无效的poitn,可以帮助您检查poitner
是否真的指向有效内存,
if (pointer != NULL)
{
pointer->quantity = 1;
pointer->value = 3.0;
strcpy(pointer->name, "My Name Is ...");
}
在这种情况下,指针是有效的,直到你决定它不是,当你这样做时,你必须像这个一样调用free()
free(pointer);
之后,如果您再次尝试访问指针,将发生未定义的行为。
1您还可以使用此语法pointer = malloc(sizeof(*pointer));
使其独立于pointer
的类型,因为sizeof(*pointer)
等于sizeof(struct Data)
它们是如何在内存中分配的?
在这两种情况下,都取决于变量的定义位置。
在命名空间范围(C++(或文件范围(C(中,它是一个全局变量,在程序启动时分配一个地址。通常,正如您所说,这是由符号表指定的。
在块范围内,它是一个自动变量,通常在程序达到定义之前的一段时间,在函数的堆栈帧上分配内存。
在类范围内,它是包含它的类的一部分
在第二种情况下,我假设存储器地址存储在32位大小的变量中
不管指针有多大,在32位平台上,它都是32位。在这种情况下,没有file_operations
对象,只有一个指针。
这两个语句都做两件事:(1(定义一个名为struct file_operations
的结构,(2(声明该类型的未初始化变量。
第一个是在堆栈上(或者在静态存储中,如果在函数之外(分配结构大小的空间。然后可以像a.member1 = 1
一样访问结构的数据成员。在函数内部时,a
在堆栈上。它就像任何其他变量声明一样,例如int a
。如果在函数外部,则声明一个全局变量。其成员地址可以使用&a
找到。编译器在编译时使用一个符号表,该表指示每个令牌的类型、相对地址等。
当声明全局变量并编译到库中时,它还会在二进制文件的符号表中生成一个符号,以便链接器可以链接它。
第二种情况声明了一个指向struct file_operations
的指针。指针是一个包含成员地址的变量,因此在您的情况下,它的大小为4字节。它的类型是struct file_operations *
,这表示它所指向的数据的类型必须是struct file_operations
。此处的变量未序列化。指针不包含有效的地址,取消对其的引用将失败。使用它:
struct file_operations a;
struct file_operations* pa = &a;
将使pa
指向a
。则a
的成员可以通过pa
经由pa->member1 = 1
进行访问。指针本身的地址&pa
也在堆栈上(或者在函数外部时在静态内存中(。&pa
是指针的地址,也就是指向指针的指针。pa
是指针指向的地址。
- 如何在 C# 中映射双 C 结构指针?
- C++:映射结构中的结构指针
- C++:添加新结构时,结构指针向量中的所有元素都会更新
- 类的静态结构指针声明在C++
- 在两个.cpp文件之间定义全局类/结构指针
- 返回对常量结构(指针类型)成员的引用:明显的左值到右值转换
- 是否可以将无符号字符数组reinterpret_cast到仅包含C++中无符号字符成员的结构指针
- 如何在地图中使用结构指针
- 结构指针在"新"调用上给出已分配的地址?
- 铸造结构指针指向C 的工会指针
- c++ 结构指针在初始化为 NULL 时无法读取内存
- 函数中的结构指针的地址为0x1
- C 用结构指针初始化结构
- C 结构指针铸成数组Interop C#
- 方法中不允许访问结构指针
- 如何打印出结构指针
- MPI_Op_create:候选功能不可行.自定义结构指针不能解释为空指针
- 尝试将结构指针传递给类时出错
- 初始化结构指针的值
- 使用 pybind11 将自定义结构(指针向量)从 C++ 传递到 python 的方法是什么?