Consolexin's blog Consolexin's blog
首页
  • 算法基础

    • 图论
    • 字符串
    • 动态规划
    • 二分
    • 滑动窗口
    • 排序
  • Project

    • CppServer
  • 相关书籍

    • 现代C++编程
  • 书籍

    • SQL必知必会
    • MySQL必知必会
分类
标签
归档
GitHub (opens new window)

Consolexinhun

小学生
首页
  • 算法基础

    • 图论
    • 字符串
    • 动态规划
    • 二分
    • 滑动窗口
    • 排序
  • Project

    • CppServer
  • 相关书籍

    • 现代C++编程
  • 书籍

    • SQL必知必会
    • MySQL必知必会
分类
标签
归档
GitHub (opens new window)
  • enum-struct-control_flow

  • memory_management

    • heap_stack
  • modern_cpp_programming
  • memory_management
consolexinhun
2022-08-04

heap_stack

进程地址空间

数据段 和 bss 段

int data[] = {1, 2}; // DATA segment memory
int big_data[1000000] = {}; // BSS segment memory
// (zero-initialized)
int main() {
    int A[] = {1, 2, 3}; // stack memory
}
1
2
3
4
5
6

data 和 bss 比栈内存大,但是访问速度较慢

栈 堆
内存 连续 allocation之内是连续的,allocation 之间是分散的
大小 小(linux 下 8MB,Windows 下 1MB) 整个系统内存
如果超限 程序在函数入口时崩溃(很难调试) 异常或者空指针
allocation(分配) 编译时 运行时
位置 高 低
线程视角 每个线程都有自己的栈 所有线程共享

局部变量要么在栈中,要么在 CPU寄存器里

int x = 3; // not on the stack (data segment)
struct A {
    int k; // depends on where the instance of A is
};
int main() {
    int y = 3; // on stack
    char z[] = "abc"; // on stack
    A a; // on stack (also k)
    void* ptr = malloc(4); // variable "ptr" is on the stack
}

1
2
3
4
5
6
7
8
9
10
11

栈性能更高,但是栈的空间有限

存在栈里的数据类型:

  • 局部变量
  • 函数参数
  • 函数返回值
  • 编译器的特别指令
  • 中断上下文

栈中每个对象在作用域外是无效的

int* f() {
    int array[3] = {1, 2, 3};
    return array;
}
int* ptr = f();
cout << ptr[0]; // Illegal memory access!! A
1
2
3
4
5
6
void g(bool x) {
    const char* str = "abc";
    if (x) {
        char xyz[] = "xyz";
        str = xyz;
    }
    cout << str; // if "x" is true, then Illegal memory access!! A
}
1
2
3
4
5
6
7
8

new/new[] 和 delete/delete[] 是C++ 关键字,用于进行动态内存分配/回收,以及在运行时对象的构造和销毁

malloc 和 free 是C关键字,分配和释放内存块(以字节为单位)

new 和 delete 的优点:

  • 语言关键字:不是函数,更加安全
  • 返回值类型:new 返回精准的数据类型,而 malloc 返回 void*
  • 失败:new 抛异常,malloc 返回空指针
  • 分配类型:new 分配的内存单元大小由编译器计算,malloc 必须手动计算分配多少字节
  • 初始化:除了分配内存单元,new 还可以初始化
  • 多态:带有虚函数的对象必须使用 new 分配

动态内存分配:

分配单个值:

int* value = (int*) malloc(sizeof(int)); // C
int* value = new int; // C++
1
2

分配 N 个元素

int* array = (int*) malloc(N * sizeof(int)); // C
int* array = new int[N]; // C++
1
2

分配 N 个结构体

MyStruct* array = (int*) malloc(N * sizeof(MyStruct)); // C
MyStruct* array = new MyStruct[N]; // C++
1
2

分配并零初始化 N 个元素

int* array = (int*) calloc(N, sizeof(int)); // C
int* array = new int[N](); // C++
1
2

释放单个元素

int* value = (int*) malloc(sizeof(int)); // C
free(value);
int* value = new int; // C++
delete value;

1
2
3
4
5

释放 N 个元素

int* value = (int*) malloc(N * sizeof(int)); // C
free(value);
int* value = new int[N]; // C++
delete[] value;

1
2
3
4
5

基本原则:

  • new 分配的对象必须用 delete 释放
  • new[] 分配的对象必须用 delete[] 释放

混用 new, new[], malloc 会导致未定义行为

delete , delete[] 用于 NULL/nullptr 空指针时不会产生错误(也是安全的)

2D 内存分配:

在栈中比较容易

int A[3][4]; // C/C++ uses row-major order: move on row elements, then columns
1

2D 动态分配和释放

int** A = new int*[3]; // allocation (pointer of pointer)
for (int i = 0; i < 3; i++)
    A[i] = new int[4]; // allocation
for (int i = 0; i < 3; i++)
    delete[] A[i]; // deallocation
delete[] A; // deallocation (pointer of pointer)
1
2
3
4
5
6

C++11 的2D动态分配和释放

auto A = new int[3][4]; // allocate 3 objects of type int[4]
int n = 3; // dynamic value
auto B = new int[n][4]; // ok
// auto C = new int[n][n]; // compile error
delete[] A; // same for B, C
1
2
3
4
5

笔记

程序不直接分配内存,而是向操作系统请求一块内存。操作系统以内存页的粒度提供内存(例如,在 linux 系统上是 4KB)

因此越界不一定导致段错误,最糟糕的情况是未定义行为

int* x = new int;
int num_iters = 4096 / sizeof(int); // 4 KB
for (int i = 0; i < num_iters; i++)
    x[i] = 1; // ok, no segmentation fault
1
2
3
4

内存泄漏是程序不再使用动态分配的内存,但是仍然维护其执行

导致的问题:

  • 非法访问:段错误,错误结果
  • 未定义:段错误,错误结果
  • 额外的内存消耗:潜在的段错误问题
int main() {
    int* array = new int[10];
    array = nullptr; // memory leak!!
} // the memory can no longer be deallocated!!
1
2
3
4
编辑 (opens new window)
上次更新: 2025/05/21, 06:42:57
struct_union

← struct_union

最近更新
01
6-其他操作
05-20
02
4-联结
05-20
03
7-管理
05-20
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Consolexinhun | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×