程序对静态对象,自动对象和动态分配的对象使用不同的内存区域

Alg*_*bra 15 c

我正在阅读"C Primer Plus"这本书并遇到一个问题,以了解记忆的区域.在书中,它指出:

通常,程序对静态对象,自动对象和动态分配的对象使用不同的内存区域.清单12.15说明了这一点.

// where.c -- where's the memory?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int static_store = 30;
const char * pcg = "String Literal";
int main(void)
{
    int auto_store = 40;
    char auto_string[] = "Auto char Array";
    int *pi;
    char *pcl;

    pi = (int *) malloc(sizeof(int));
    *pi = 35;
    pcl = (char *) malloc(strlen("Dynamic String") + 1);
    strcpy(pcl, "Dynamic String");

    printf("static_store: %d at %p\n", static_store, &static_store);
    printf("  auto_store: %d at %p\n", auto_store, &auto_store);
    printf("         *pi: %d at %p\n", *pi, pi);
    printf("  %s at %p\n", pcg, pcg);
    printf(" %s at %p\n", auto_string, auto_string);
    printf("  %s at %p\n", pcl, pcl);
    printf("   %s at %p\n", "Quoted String", "Quoted String");
    free(pi);
    free(pcl);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

运行代码并获取:

static_store: 30 at 0x10a621040
  auto_store: 40 at 0x7ffee55df768
         *pi: 35 at 0x7fbf1d402ac0
  String Literal at 0x10a620f00
 Auto char Array at 0x7ffee55df770
  Dynamic String at 0x7fbf1d402ad0
   Quoted String at 0x10a620f9b
Run Code Online (Sandbox Code Playgroud)

这本书的结论:

如您所见,静态数据(包括字符串文字)占用一个区域,自动数据占用第二个区域,动态分配数据占第三个区域(通常称为内存堆或免费存储).

我可以发现他们的地址不同.我怎么能保证他们属于不同的地区?

Lun*_*din 19

不同地区的地址差别很大.如果他们在同一地区,他们会有类似的地址.更好的例子,我们在每个区域分配2个对象:

#include <stdio.h>
#include <stdlib.h>

int main (void)
{
  int stack1;
  int stack2;
  static int bss1;
  static int bss2;
  static int data1=1;
  static int data2=1;
  int* heap1 = malloc(1);
  int* heap2 = malloc(1);  
  char* rodata1 = "hello";
  char* rodata2 = "world";

  printf(".stack\t%p %p\n",  &stack1,  &stack2);
  printf(".bss\t%p %p\n",    &bss1,    &bss2);
  printf(".data\t%p %p\n",   &data1,   &data2);
  printf(".heap\t%p %p\n",   heap1,    heap2);
  printf(".rodata\t%p %p\n", rodata1,  rodata2);

  free(heap1);
  free(heap2);
}
Run Code Online (Sandbox Code Playgroud)

输出(例如):

.stack  000000000022FE2C 000000000022FE28
.bss    0000000000407030 0000000000407034
.data   0000000000403010 0000000000403014
.heap   0000000000477C50 0000000000477C70
.rodata 0000000000404000 0000000000404006
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,同一段中的两个变量具有几乎相同的地址,唯一的区别是对象的大小(可能还有一些对齐空间).虽然与其他段中的变量相比,它们具有非常不同的地址.

  • (字符串文字不一定以.rodata结尾,但是您可以理解) (2认同)

dbu*_*ush 9

C标准规定,一个对象可以有4周不同的一个存储的持续时间.这些是:

  • 静态的
  • 自动
  • 分配
  • 线

上面的代码解决了前三个问题.

一个静态对象要么在文件范围或局部范围与声明的static修改.字符串文字也是静态对象.

一个自动对象,典型地被称为一个局部变量,它的功能或者一个封闭的范围内声明.

一个分配的对象是其存储器由分配函数返回等malloc.

实际上,编译器通常会将这些对象类型中的每一个放在不同的内存区域中.静态对象通常放置在可执行文件的数据部分中,自动(读取:本地)对象通常存储在堆栈中,并且分配的对象通常存储在堆上.

字符串文字特别是静态对象,通常放在标记为只读的数据部分的特殊部分中.

这些区域通常位于不同的不同存储区域中,但是它们不是必需的.因此,在实践中,每个区域中的对象的地址将明显不同,它们不是必需的.

因此,您并不需要"确保"不同类型的变量位于不同的区域.编译器会根据您的定义来处理这些问题.