【问题标题】:C Dynamic Memory vs Stack Memory VariablesC 动态内存与堆栈内存变量
【发布时间】:2016-02-07 21:46:05
【问题描述】:

当使用 malloc 创建 C 数组时,该数组存储在堆中,而当静态创建 C 数组时,它存储在堆栈中。但是,如果返回从函数静态初始化的 C 数组的元素会怎样?我的措辞可能很奇怪,所以这里是一个例子:

#include <stdio.h>
#include <stdlib.h>
char getStaticElement();
char getDynamicElement();

int main() {
    char dynamicElement = getDynamicElement();
    char staticElement = getStaticElement();
    printf("Dynamic Element: %c\n", dynamicElement);
    printf("Static Element: %c\n", staticElement);
    return 0;

}
char getStaticElement() {
    char staticArray [] = {'a','b','c'};
    return staticArray[1]; // returns b
}
char getDynamicElement() {
    char * dynamicArray = malloc(sizeof(char)*4);
    dynamicArray [0] ='a';
    dynamicArray [1] ='b';
    dynamicArray [2] ='c';
    dynamicArray [3] ='\0';
    return dynamicArray[1]; // returns b
}

那么内存中的staticElement在哪里呢? staticArray 是因为函数完成而从堆栈中清除,还是因为 staticArray 的元素已返回而仍在堆栈中?
注意:我知道我没有释放动态数组,并且正在泄漏内存,这只是一个示例,并不打算使用。

【问题讨论】:

  • C 标准不需要堆栈或堆。你能指望什么?为什么?
  • 我想知道为什么我不必担心 staticElement 在内存中的位置,尽管函数 getStaticElement 已经结束了
  • 另外,我不知道 C 标准不需要堆栈或堆,我很抱歉,我的教授告诉我们,如果 C 程序变量不是动态创建的(malloc , calloc, realloc ...) @Olaf
  • @Turtle 几乎每个人都使用术语“堆栈”和“堆”来表示这样的事情。 C 规范使用“自动存储持续时间”和“动态存储持续时间”这两个术语,它们更具技术性、更便携,但在口语中使用频率较低。
  • 你的教授谈到了一个具体的实现。然而,现代编译器使用高级寄存器分配甚至在寄存器中保存和传递(小)数组和structs 也是错误的。他可能想更新他从 80 年代至今的知识。 (我非常了解这样的导师)。事情远没有过去那么简单。

标签: c arrays memory memory-management


【解决方案1】:

在 C 中,如果您从函数返回 charint,则您从函数返回该值的 副本,而不是实际对象本身。换句话说,如果您返回声明为局部变量的数组的元素,您实际上是返回了该数组元素的 copy,因此即使原始数组被销毁,也不必担心您以某种方式“丢失”了该数组元素。同样,如果您返回分配有malloc 的数组的元素,您将返回数组元素的副本,而不是元素本身。这就是为什么你没有在上面的代码中得到垃圾值的原因。

返回的值不一定存储在堆栈或堆中。它通常存储在某个地方的寄存器中。从语言的角度来看,它具有自动存储持续时间,因此会自动清理。由于您将该值存储在局部变量中,因此它将存储在堆栈中(或者,从技术上讲,它具有自动存储持续时间),但那是因为您将它放在局部变量中并且与事实无关它最初位于动态或静态分配的数组中。

也就是说,您正在泄漏内存,因为您从来没有free 使用malloc 分配的数据。

【讨论】:

  • 非常感谢!我知道它正在泄漏内存,这只是我无意运行的示例程序。我想澄清一下,我正在返回一个动态分配的元素,因为我的问题措辞有些尴尬。
  • 当我返回一个不是使用 malloc 创建的 char * 时会怎样?也会被复制吗?
  • 在这种情况下,char* 被复制,但不是它指向的东西。这就是您需要动态分配的原因。
猜你喜欢
  • 2011-04-25
  • 1970-01-01
  • 2011-08-15
  • 2012-09-06
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
相关资源
最近更新 更多