什么时候应该在C中使用malloc,什么时候不使用?
我了解malloc()如何工作。 我的问题是,我会看到这样的事情:
#define A_MEGABYTE (1024 * 1024) char *some_memory; size_t size_to_allocate = A_MEGABYTE; some_memory = (char *)malloc(size_to_allocate); sprintf(some_memory, "Hello World"); printf("%s\n", some_memory); free(some_memory);
为了简洁,我省略了错误检查。 我的问题是,你不能通过初始化一个指向内存中的静态存储的指针来完成上述操作吗? 也许:
char *some_memory = "Hello World";
你到底需要自己分配内存,而不是声明/初始化你需要保留的值?
char *some_memory = "Hello World";
正在创build一个指向string常量的指针。 这意味着string“Hello World”将在内存的只读部分中的某处,并且只有一个指向它的指针。 您可以使用string作为只读。 您无法对其进行更改。 例:
some_memory[0] = 'h';
正在寻求麻烦。
另一方面
some_memory = (char *)malloc(size_to_allocate);
正在分配一个char数组(一个variables)和some_memory指向那个分配的内存。 现在这个数组是可读写的。 你现在可以做:
some_memory[0] = 'h';
并将数组内容更改为“hello World”
对于这个确切的例子,malloc没有什么用处。
malloc需要的主要原因是数据必须具有与代码范围不同的生命周期。 你的代码在一个例程中调用malloc,将指针存储在某个地方,最终在另一个例程中调用free。
第二个原因是C没有办法知道堆栈中是否有足够的空间来进行分配。 如果你的代码需要100%健壮,那么使用malloc会更安全,因为那么你的代码就可以知道分配失败并处理它。
与静态声明相比,malloc是一个很好的工具,用于在运行时分配,重新分配和释放内存,比如hello world例子,这些例子在编译时被处理,因此不能被改变大小。
因此,在处理任意大小的数据时,malloc总是有用的,比如读取文件内容或处理套接字,而您不知道要处理的数据的长度。
当然,在一个简单的例子中,malloc不是正确的工具,但是对于更复杂的情况(例如在运行时创build一个任意大小的数组),它是唯一走。
char *some_memory = "Hello World"; sprintf(some_memory, "Goodbye...");
是非法的,string文字是const
。
这将在堆栈或全局(取决于声明的位置)分配一个12字节的char数组。
char some_memory[] = "Hello World";
如果你想留下进一步操作的空间,你可以指定数组的大小。 (请不要把1MB放在堆栈上)
#define LINE_LEN 80 char some_memory[LINE_LEN] = "Hello World"; strcpy(some_memory, "Goodbye, sad world..."); printf("%s\n", some_memory);
有必要分配内存的一个原因是如果你想在运行时修改它。 在这种情况下,可以使用堆栈上的malloc或缓冲区。 将“Hello World”分配给指针的简单示例定义了“典型”不能在运行时修改的内存。
如果您不知道需要使用的内存的确切大小,则需要dynamic分配( malloc
)。 一个例子可能是用户在应用程序中打开一个文件。 您需要将文件的内容读入内存,但是当然由于用户在运行时在现场select了文件,因此您不会事先知道文件的大小。 所以基本上你需要malloc
当你不知道你正在使用的数据的大小。 至less这是使用malloc
主要原因之一。 在你的例子中,一个简单的string,你已经知道在编译时的大小(加上你不想修改它),dynamic分配它没有多大意义。
稍微偏离主题,但是…使用malloc
时,必须非常小心,不要造成内存泄漏。 考虑这个代码:
int do_something() { uint8_t* someMemory = (uint8_t*)malloc(1024); // Do some stuff if ( /* some error occured */ ) return -1; // Do some other stuff free(someMemory); return result; }
你看这个代码有什么问题吗? malloc
和free
之间有一个条件返回语句。 一开始可能看起来不错,但考虑一下。 如果出现错误,您将返回而不释放您分配的内存。 这是内存泄漏的常见来源。
当然,这是一个非常简单的例子,在这里很容易看出错误,但是想象一下,有数百行代码遍布指针, malloc
, free
和各种error handling。 事情真的很麻烦。 这是我在现实中更喜欢现代C ++而不是C的原因之一,但这是一个完整的主题。
所以每当你使用malloc
,一定要确保你的内存尽可能的free
。