【问题标题】:How are memory segments organized from the point of view of program [closed]从程序的角度来看,内存段是如何组织的[关闭]
【发布时间】:2014-07-12 07:32:43
【问题描述】:

首先,我给出了 C/C++ 函数的两个代码片段,它们揭示了 C/C++ 管理内存分配的不同策略。我在一次求职面试中被问到这些问题。:(

#1

char *func()
{
    char *p = "hello world";
    return p;
}

#2

char *func()
{
    char p[] = "hello world";
    return p;
}

当函数返回时,人们还能得到字符串“hello world”吗?
这个答案分别是YES和NO。
因为在#1 中,“hello world”是一个字符串常量。而在#2中,“hello world”的存储位置是STACK。但是这样写的时候,static char p[] = "hello world";,答案是YES。

那么,我的问题是 C/C++ 如何管理函数的内存分配
回想面试官告诉我的话。我记得类似堆栈/堆/数据段/程序段/*。我希望任何人都可以准确地描述这一点。
谢谢。


添加内容

“了解代码在内存中的管理方式将有助于程序员编写代码。”这是面试官对我说的。
上面给出的示例用于描述这一点。我想问的是从程序的角度来看,内存段是如何组织的。我期待的答案可能会像

|___________________|  
|        STACK      |
|___________________|  
|        HEAP       |
|___________________|  
|   DATA SEGMENT    |
|___________________|  
|  PROGRAM SEGMENT  |
|___________________|  
|        ...        |  
|                   |  

从程序的角度来看,我不确定这样的内存分区是否正确。 (而且,可能存在其他存储特定类型数据的段。)

【问题讨论】:

标签: c++ c function memory


【解决方案1】:

正如所写,您的问题过于宽泛,无法完全解决,因此我将在此处针对其中的特定部分进行解决。

在第一个示例中,我们返回字符串文字的地址,该地址通常存储在程序段中进程内存的只读部分中。你可以在this answer阅读更多内容。

char *p = "hello world";
return p;

在第二个示例中,我们在堆栈上创建一个字符数组char[],并通过复制字符串文字来填充它。每当我们在C 中声明一个非静态数组时,内存总是分配在堆栈上。由于函数返回时堆栈内存有效地消失了,因此指针在函数返回时无效。

char p[] = "hello world";
return p;

在第三个也是最后一个示例中,我们声明了一个静态数组。在函数内部,static 关键字意味着变量的生命周期等于整个程序的生命周期。这就是为什么返回一个指向这样一个数组的指针是完全有效的,即使它是一个副本,就像第二个例子一样。

static char p[] = "hello world";

如果你对这类知识感兴趣,我会推荐this slide deck进一步学习。它非常实用,并在面试环境中讨论了这些问题。

【讨论】:

    【解决方案2】:

    第一个没问题,返回的指针指向一个常量文字(但是修改它是未定义的行为,它应该是const)。

    第二个可能会导致未定义的行为,它返回一个指向局部变量的指针,该变量将在退出函数后被破坏。

    注意:常量字面量将存储在 DATA-SEGMENT(在大多数实现中)而不是函数的堆栈中。

    【讨论】:

    • 我很失望地发现gcc -Wall 没有对char *p = "hello world"; 发出警告:-(
    • 我认为这是因为,那段代码在 C 中是有效的(历史上!)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-18
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多