首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >自动内存分配与动态内存分配:要考虑什么?

自动内存分配与动态内存分配:要考虑什么?
EN

Stack Overflow用户
提问于 2018-06-03 22:52:31
回答 2查看 1.1K关注 0票数 2

在C中,我们可以分配内存automaticallydynamically

代码语言:javascript
复制
size_t foo = 128;
char str1[64];            // Automatic
char str2[foo]            // Automatic (variable-length, C99)
char *str3 = malloc(64);  // Dynamic
char *str4 = malloc(foo); // Dynamic

对于自动分配,变量的作用域是有限的,内存通常是在堆栈上分配的,而动态分配使用堆。

让我们继续使用字符串,假设函数应该返回它以某种方式创建的字符串。似乎有两种常见的做法,都可以在标准库函数中看到:

获取缓冲区和大小,然后使用malloc()将缓冲区写入到提供的buffer

  • Allocate中,并返回指向它的指针

第一种方法的优点是我们不需要记住free()内存。另一方面,我们需要提交两个额外的参数,并以某种方式从外部确定缓冲区应该有多大:

代码语言:javascript
复制
char str1[128];              // Let's hope this is large enough!
fill_my_buffer(str1, 128);   // Might need more than 128, who knows

char *str2 = return_a_ptr(); // Just give me a pointer
size_t len = strlen(str2);   // Ah, so that's what we got!

在C中选择自动或动态内存分配时,应该考虑哪些(其他)考虑因素?

这个问题是以意见为基础的,但我相信应该可以为这两种方法编制一个客观利弊的综合列表,这样就可以在个案的基础上做出明智的决定。

EN

回答 2

Stack Overflow用户

发布于 2018-06-04 00:15:17

一条经验法则是,您应该避免在堆栈上进行“大”分配。一两个页面(4096字节)就可以了,但是任何更大的页面都应该是堆分配的。

改变堆栈指针太多会降低缓存性能,缓存才是王道。

此外,您可能会溢出堆栈并错过保护页,尽管这主要是必须具有有限大小堆栈的线程的问题,或者在其他受限制的系统上不能自动主线程堆栈增长的问题。

除此之外,主要的问题是语义:这个(小)对象是否“属于”这个堆栈框架,或者它是否需要存在一段不同的时间(更长或更短)。

调用free的需求根本不应该是一个问题,有各种各样的函数总是必须成对调用的(这是C++试图解决的主要问题,也是GNU的__attribute__((cleanup))扩展),你应该养成总是知道去做的原则。

值得注意的是,每个接受指针的函数都应该有一个“谁负责这个所有权”的概念。常见的所有权模型包括:借用(由一些更高的堆栈框架拥有)、唯一拥有和共享(通常重新计算)所有权,尽管可能有几十种微妙的变体(尽管不是所有的都在同一个程序中)。

票数 3
EN

Stack Overflow用户

发布于 2018-06-03 23:03:38

这基本上是一个判断调用-调用代码能知道缓冲区可能有多大吗?

  • 如果是这样,最好是它提供缓冲区,并且被调用的代码必须确保它不会溢出它(这反过来意味着接口必须指定所提供的缓冲区的大小)。
  • 如果没有,则被调用的代码应该分配并返回内存。

调用者提供的缓冲区的复杂之处在于“当提供的空间不够大时该怎么办”。调用者提供的缓冲区的复杂之处在于确保它被适当地释放,并决定在内存分配失败时如何处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50667681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档