1)
对于哪些数据类型,我必须使用malloc分配内存?
2)
为什么我可以运行此代码?为什么不崩溃?我假设我需要先为结构分配内存。
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint32;
typedef struct
{
int a;
uint32* b;
}
foo;
int main(int argc, char* argv[])
{
foo foo2;
foo2.a = 3;
foo2.b = (uint32*)malloc(sizeof(uint32));
*foo2.b = 123;
}
使用
不是更好foo* foo2 = malloc(sizeof(foo));
第3) foo.b如何设置?是引用随机内存还是NULL?
#include <stdio.h>
#include <stdlib.h>
typedef unsigned int uint32;
typedef struct
{
int a;
uint32* b;
}
foo;
int main(int argc, char* argv[])
{
foo foo2;
foo2.a = 3;
}
答案 0 :(得分:18)
C中的所有类型都可以动态,自动(在堆栈上)或静态分配。问题不是类型,而是你想要的生命周期 - 当你希望一个对象存在于创建它的函数范围之外时,或者你事先不知道你需要多大的东西时,你可以使用malloc。
答案 1 :(得分:9)
编辑以解决您编号的问题。
您必须使用malloc分配数据类型。只有当您希望指针类型指向有效内存时,才能使用一元&
(地址)运算符或malloc()
或某些相关函数。
您的代码没有任何问题 - 行:
foo foo2;
在堆栈上分配一个结构 - 然后一切正常。在这个意义上,结构与任何其他变量没有区别。使用自动变量(堆栈分配)或全局变量或malloc()
并不是更好或更糟,它们都是不同的,具有不同的语义和选择它们的不同理由。
在#3的示例中,foo2.b
的值未定义。在您明确初始化它之前,任何自动变量都有一个未定义和不确定的值。
答案 2 :(得分:3)
您必须使用malloc
分配您希望手动管理的任何内存,而不是自动分配。如果存储的是int
或double
或struct
或其他内容,则无关紧要; malloc
就是手动内存管理。
当你创建一个没有malloc
的变量时,它存储在堆栈中,当它超出范围时,它的内存会自动回收。当变量不再可访问时,变量超出范围;例如当声明变量的块或函数结束时。
使用malloc
分配内存时,它存储在堆中,malloc
返回指向此内存的指针。直到你在其上调用free
之后才会回收此内存,无论指针是否仍然可以访问(当没有指针留给堆分配的内存时,这是内存泄漏)。这意味着您可以继续使用在分配的块或函数之后分配的内存,但另一方面,您现在有责任在完成它时手动释放它。
在您的示例中,foo2
位于堆栈中,并在main
结束时自动取消分配。但是,foo2.b
指向的内存将不自动解除分配,因为它位于堆上。这在您的示例中不是问题,因为在程序结束时所有内存都返回到操作系统,但如果它位于main
以外的函数中,则会导致内存泄漏。
答案 3 :(得分:2)
foo foo2;
自动在堆栈上分配结构,当封闭函数(在本例中为main
)结束时,它会自动释放。
如果需要在封闭范围结束后保持结构,则只需使用malloc
在堆上分配内存。当对象太大而无法放入堆栈时,您可能还需要执行此操作。
答案 4 :(得分:2)
2)为什么我可以运行此代码?它为什么不崩溃?
代码从不引用未定义的内存或NULL。为什么会崩溃? (你写的内存泄漏,但可能是因为你只显示部分代码而且在给定的程序中它不是问题。)
您建议的替代代码也可以使用,但默认情况下,从malloc
返回的内存也未初始化。 (我曾经使用过一个自定义内存分配器,默认情况下用?
个字符填充返回的内存块。规则仍然完全合法。注意calloc
返回一个指向零初始化内存的指针;如果{这就是你想要的。)
3)
foo.b
如何设定?是引用随机存储器还是NULL?
随机记忆。堆栈分配的结构不会为您初始化。
答案 5 :(得分:1)
你可以做到,但这还不够。
因为,第二个字段是指针,必须将其设置为有效地址。其中一种方法是分配内存(使用malloc)。
至于你的第一个问题 - 必须手动管理对象的生命周期时使用malloc。
例如,第二个代码可以重写为:
int main(int argc, char* argv[])
{
foo foo2; uint32 b;
foo2.a = 3;
foo2.b = &b;
*foo2.b = 123;
}
这样更好,因为生命周期是相同的,内存现在处于堆栈状态 - 并且不需要被释放。
答案 6 :(得分:1)
结构实例(“foo2”)的内存将在堆栈上分配 - 不需要为此自己分配内存 - 如果使用malloc进行分配,请务必在以后释放内存。 / p>