【问题标题】:Assigning a malloc'd variable value to a new variable, is the new variable also on heap memory?将 malloc 的变量值分配给新变量,新变量是否也在堆内存上?
【发布时间】:2014-05-22 02:19:42
【问题描述】:

我对以下新变量“num2”是否也在堆内存上感到困惑,因为我为它分配了“num1”值,而 num1 被分配给了堆内存。

int main()
{

    int *num1 = malloc(sizeof(int)); /* assign num1 to heap memory */
    *num1 = 7;

    int num2 = *num1;               /* assign num1's value to num2, is num2 also on heap?*/


    return 0;
}

【问题讨论】:

  • 不,它在您的堆栈中...变量的存储不会因为您将值复制到其中而改变。
  • 有没有办法在不做 malloc 或 calloc 的情况下将 num2 放在堆内存上?是否可以使用一些复制功能(如 memcpy)?谢谢
  • 自动(matic)变量总是进入堆栈。您可以将其声明为静态以使其进入数据段。但是对于堆,您需要 malloc 或指向之前分配的内存块。
  • 在这种情况下如何指向以前 malloc 的内存块?谢谢
  • @TonyGW :如果没有明确的malloccalloc,您将无法访问堆内存。虽然如果您正在使用内存较小的嵌入式系统,您可以直接访问堆内存地址并尝试对其进行操作,但这是一种肮脏且不友好的方式。

标签: c memory heap-memory


【解决方案1】:

变量num1num2 都是自动变量,这意味着它们会自动分配到堆栈上。变量具有函数范围。一旦定义了它们的函数返回,它们就会从堆栈中释放,即它们不再存在并且试图访问它们是未定义的行为。

在函数内部定义的变量(包括函数参数)并且不是static 是自动变量。函数调用时自动在栈上创建,函数返回时销毁。因此,它是函数的局部变量,即它具有函数作用域。

在任何函数之外定义的变量称为全局变量。静态变量和全局变量都有static storage duration,这意味着它们既不是在堆栈上也不是在堆上分配,而是在文本段(如果它们是const)或程序内存布局的数据段中,甚至分配到它自己的内存段上最现代的机器。需要注意的重要一点是,内存在程序开始执行时被分配一次,并且永远不会被释放,因为全局变量和静态变量的生命周期贯穿程序的整个运行。此外,如果未显式初始化,全局和静态变量默认初始化为零。阅读这个 - The initialization of static variable in C

您不能创建堆上的变量,即,标识符不能绑定到堆上的内存位置。您可以在堆上分配内存并将指向它的指针存储在变量中,但变量本身不在堆上。如果变量是本地且非静态的,则它在堆栈上,否则它在文本段或数据段中。阅读本文了解更多详情 - Memory Allocation in C Programs

【讨论】:

    【解决方案2】:

    每当您使用malloc 时,都会在堆中分配内存(如果内存可用)。

    在你的情况下,num1 是指向堆中内存的指针,而你 malloc 它。 (num1 指针仅存在于堆中。)

    int num2 = *num1;
    

    当您使用上述语句时,您所说的是获取num1 所指向的任何值并分配num2

    int num2 表示您希望在当前堆栈帧的堆栈中创建内存。

    要在没有 malloc 的情况下分配内存,您可以尝试 globalstatic。它将在Data segment 的编译时为其分配内存。但是根据我的知识你不能直接分配堆

    例如取全局变量。

    int num2;
    
    int main()
    {
      // do something
    } 
    

    memcpy() 仅将值从一个位置复制到另一个您需要已初始化内存的位置,该内存可以位于堆或堆栈中。

    【讨论】:

      【解决方案3】:

      Q新变量是否在堆上?

      A没有,详情可以看What and where are the stack and heap?

      【讨论】:

      • 不要只是发布链接,向OP解释答案。如果您认为这两个问题相似,则将 OP 的问题标记为重复,而不是在此处发布其他答案。
      【解决方案4】:

      您对pointermemory 感到困惑。当您使用malloc 时,您将获得所需大小的堆内存,即地址范围为startAddrendAddr 的字节集合。现在您已经分配了堆内存,但是您将如何访问它,因为它是连续的,您只需要知道起始地址 (startAddr) 和内存块的大小(您自己分配它时已经知道)。

      这个startAddr是在成功分配内存后由malloc返回的。您可以将其保存在单个指针中,也可以将该 地址(不是整个分配的内存)复制到其他指针。

      现在栈和堆内存的区别:

      每当您声明任何不是globalregisterstatic 的变量(指针也是存储地址的变量)时,它总是进入堆栈。堆只能用于动态分配,并且只能由alloc 系列函数访问。

      总结:

      num1num2 两个指针都在堆栈上,因此只能在当前功能块内访问。

      虽然num1(和num2)指向的地址在整个程序可用的堆内存中,即具有此地址的任何其他函数(或多线程程序中的线程)都可以访问分配的堆内存。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-23
        • 2019-10-03
        • 2019-01-17
        • 1970-01-01
        • 2014-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多