内存安全程序设计

SyEic_L MVP++

Temporal Memory Problems

  • Use After Free
  • Double Free
  • Memory Leak
  • Dangling Pointer

RAII

  • Resource Acquisition Is Initialisation

  • Constructor Acquires, Destructor Release

  • 资源获取放在构造函数中,资源删除放在析构函数中

  • local创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class FileObj{
public:
FILE* ptr;
FileObj(char* name){
ptr = fopen(name, "r");
}

~FileObj(){
fclose(ptr);
}
};

void printFile(const char* name){
FileObj fobj; //本地栈上创建对象
}

C++ Smart Pointer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template <typename T> class ToyPtr{
public:
explicit ToyPtr(T *ptr):ptr_(ptr){}
~ToyPtr() { delete ptr_; }
T & operator*() { return *ptr_; }
T * operator->() { return ptr_; }

private:
T *ptr_;
}

int main(){
ToyPtr<int> int_sp (new int(8));
}

unique_ptr

  • Exclusive ownership
  • Lightweight pointer
  • Destroys the object when goes out of scope by invoking delete() in destructor
1
2
3
4
5
6
7
8
#include <memory>  // for std::unique_ptr

int main() {
// unique_ptr points to heap variable; never used delete, but no leak
std::unique_ptr<int> x(new int(5));
(*x)--; // 4
return 0;
}
  • Initialization

    • Constructor
      T *pT = new T();
      std::unique_ptr<T> p1 (pT);
      std::unique_ptr<T> p2 (new T());
    • Make_unique
      std::unique_ptr<T> p3 = make_unique<T>();
    • Move
      std::unique_ptr<T> p4 = std::move(p1);
  • Cannot be copied(相当于浅拷贝)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <memory>  // for std::unique_ptr

    int main() {
    std::unique_ptr<int> x(new int(5));
    std::unique_ptr<int> y(x); // False
    std::unique_ptr<int> z;
    z = x; // False
    return 0;
    }
  • Transfer

    • release() returns the pointer, sets wrapped pointer to nullptr
    • reset()delete’s the current pointer and stores a new one
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <memory>  // for std::unique_ptr
    int main() {
    std::unique_ptr<int> x(new int(5));
    std::unique_ptr<int> y(x.release()); // y gets the ownership from x
    std::unique_ptr<int> z(new int(8));
    // y transfers ownership of its pointer to z; z’s old pointer was deleted.
    z.reset(y.release());
    return 0;
    }
  • Move Equivalent to “release-and-reset”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Std::string returnString(){
    std::string x("foo");
    return x;
    }

    int main() {
    std::string a("hello");
    std::string b = std::move(a); // move a to b
    b = std::move(returnString()); // move the returned value into b
    return 0;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <memory>  // for std::unique_ptr
    int main() {
    std::unique_ptr<int> x(new int(5));
    std::unique_ptr<int> y = std::move(x); // y gets the ownership from x
    std::unique_ptr<int> z(new int(8));
    // y transfers ownership of its pointer to z; z’s old pointer was deleted.
    z = std::move(y);
    return 0;
    }

shared_ptr

  • Shared ownership
  • Destroys the object when last reference is released
  • reference counting
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <memory> // for std::shared_ptr

int main(int argc, char **argv) {
std::shared_ptr<int> x(new int(10)); // ref count for “10” node: 1
std::shared_ptr<int> y = x; // ref count for “10” node: 2
auto z(y); // ref count for “10” node: 3
auto w = make_shared<int>(100); // ref count for “100” node: 1
return 0;
} // ref count: 0
  • 不可以用裸指针创建多个shared_pointer,只能创建第一个,其他的需要用拷贝或者赋值等方法来创建

weak_ptr

  • similar to a shared_ptr but doesn’t affect the reference count. It can be used to break the cycle reference problem.

Spatial Memory Problems

  • Buffer overflow
  • Null pointer dereferencing
  • Dereference uninitialized pointer

Fat-pointer

1
2
3
4
5
6
7
p = malloc(size);
p_base = p;
p_bound = (p != 0) ? (p + size) : 0;

if (p < p_base || p >= p_bound)
raise exception();
*p = … or … = *p;

Meta-data Storage

  • shadow space
  • a hash table
  • a trie data structure

Meta-data Update

  • Title: 内存安全程序设计
  • Author: SyEic_L
  • Created at : 2025-05-15 22:58:03
  • Updated at : 2025-05-15 22:58:03
  • Link: https://blog.syeicl.vip/2025/05/15/内存安全程序设计/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments