如何从程序的角度组织内存段

时间:2014-07-12 07:32:44

标签: c++ c function memory

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

#1

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

#2

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

人们还能得到字符串" hello world"当func返回时?
这个答案分别是YES和NO 因为在#1,"你好世界"是一个字符串常量。在#2中," hello world"是STACK。但是当以这种方式写作static char p[] = "hello world";时,答案将是肯定的。

所以,我的问题是 C / C ++如何管理函数的内存分配
回顾我的面试官告诉我的事情。我记得像STACK / HEAP / DATA SEGMENT / PROGRAM SEGMENT / *这样的东西。我希望任何人都能准确地描述这一点 感谢。


已添加内容

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分: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进一步研究。这是非常实际的,并在访谈的背景下讨论这些问题。