我将malloc
的内存分配给struct
的指针,但我没有为实际的struct分配任何内容。但是,我可以访问/使用struct
。
typedef struct A
{
int w;
int x;
int y;
int z;
}A;
int main(void)
{
A* a = malloc(sizeof(A*)); //Here I allocate memory just to pointer to A
//Why can I do this than?:
a->z = 10;
a->w = 456;
return 0;
}
为什么这样做? 这只是巧合,还是总是以这种方式工作? 一些说明:
我无法使用非动态分配
答案 0 :(得分:2)
malloc
调用分配请求的字节数并返回指针
到分配的内存块的开始。
A* a = malloc(sizeof(A*));
在这里,您要求sizeof(A*)
个字节,但是您需要的字节数
请求是指向A
的指针。但是你需要a的字节数
A
对象,可能不一样。这似乎是一个小的差异,但它
是一个巨大的。你应该做的是:
A *a = malloc(sizeof(A));
甚至更好
A *a = malloc(sizeof *a);
第二个更好,因为你不能犯错误,它总会传递给
malloc正确的字节数。使用sizeof(<type>)
很容易
错误并在不需要时添加*
,就像您使用sizeof(A*)
一样。
我无法通过非动态分配
来做到这一点
嗯,你可以。对于一个简单的结构,您可以初始化它而无需从中请求内存
堆(通过malloc
):
A a;
a.z = 10;
a.w = 456;
或
A a = { .z = 10, .w = 456 };
也会这样做。
我们通常选择使用malloc
作为结构的原因是结构
可能非常大,可能需要很多字节的内存。您拥有的空间量
变量函数的堆栈框架与之相比非常小
你在堆部分的内存。因此,从中请求内存会更好
使用malloc
的堆。它还允许您将该指针传递给其他人
函数,即使在请求内存结束的函数之后也是如此。
你已经忘记了两件事:
malloc
的返回,可能是NULL
。最后释放内存。当你不需要记忆时:
free(a);
答案 1 :(得分:2)
执行此操作时:
A* a = malloc(sizeof(A*));
您没有为A
的实例分配足够的内存。因此,如果您读/写任何碰巧超出实际分配范围的成员,则调用undefined behavior。
对于未定义的行为,您无法准确预测节目的输出。它可能会崩溃,可能会输出奇怪的结果,或者(在您的情况下)它可能看起来正常工作。未定义的行为清单如何通过进行看似无关的修改(例如额外的局部变量,调用printf
进行调试或使用不同的选项重新编译)来改变。
仅仅因为某个程序 崩溃并不意味着它将。
如果您使用valgrind之类的工具,它可以在您错误地使用内存时捕获,例如在您的示例中。
答案 2 :(得分:1)
实际上,这将取决于实际的CPU架构和操作系统,以确定它是否有效:
第一个问题是:什么是sizeof(A)
什么是sizeof(A *)
?
我不知道任何不等式sizeof(A) <= sizeof(A *)
为真的CPU,但CPU(或具有外部存储器电路的计算机)至少是可能的。
在这种情况下,您的代码将正常工作,因为malloc
分配了足够的内存来保存结构A
。
如果没有给出这个条件,则取决于malloc
的实际实施情况。许多实现将对malloc
的参数进行舍入,因此malloc(5)
实际上将分配16个字节,而不是5个字节。
如果malloc
将分配多达sizeof(A)
个字节,那么一切都很好。
如果malloc
分配的sizeof(A)
字节少于#include <stdio.h>
extern void iplus(long *a, long *b, long *c){
printf("Starting\n");
long r= *a + *b;
printf("R setup\n");
*c=r;
printf("Done\n");
}
,则取决于是否使用分配内存后的内存以及是否存在的问题:
如果分配的内存之后的内存不存在(例如,在使用MMU时未映射),则会出现错误,具体取决于系统 - 在大多数现代计算机上都会出现“异常”,程序将崩溃。
如果该内存之后的内存被其他一些数据占用,您将覆盖该数据,这可能会导致错误。
如果该存储器之后的存储器存在但未使用,则程序将正常工作。
答案 3 :(得分:0)
没有人说你应该做什么。这样做:
int main(void)
{
A* a = malloc(sizeof(A)); // Here I allocate an ins6tance of A and set a pointer to it
a->z = 10;
a->w = 456;
return 0;
}