string *sp = new string("a value"); // 分配并初始化一个string对象
string *arr = new string[10]; // 分配10个默认初始化的string对象
当我们使用一条 new 表达式时, 实际执行了三步操作:
-
new 表达式调用一个名为 operate new(或者 operate new[])的标准库函数. 该函数 (从自由存储区上) 分配一块足够大的, 原始的, 未命名的内存空间 (无需指定内存块的大小) 以便存储特定类型的对象(或对象的数组).
-
编译器运行相应的构造函数以构造这些对象, 并为其传入初值.
-
对象被分配了空间并构造完成, 返回一个指向该对象的指针.
delete sp; // 销毁*sp, 然后释放sp指向的内存空间
delete [] arr; // 销毁数组中的元素, 然后释放对应的内存空间
当我们使用一条 delete 表达式删除一个动态分配的对象时, 实际执行了两步操作:
-
对 sp 所指的对象或者 arr 所指的数组中的元素执行对应的析构函数.
-
编译器调用名为 operate delete(或者 operate delete[]) 的标准库函数释放内存空间.
-
malloc 需要显式的指出内存大小: 函数接受一个表示待分配字节数的 size_t.
-
返回指向分配空间的指针 (void*) 或者返回 0 以表示分配失败. (从堆上动态分配内存)
-
free 函数接受一个 void*, 它是 malloc 返回的指针的副本, free 将相关内存返回给系统. 调用 free(0) 没有任何意义.
// operate new的一种简单实现
void *operater new(size_t size) {
if (void *men = malloc(size))
return mem;
else
throw bad_alloc();
}
// opearte delete的一种简单实现
void operator delete(void *mem) noexcept { free(mem); }
-
当对象的值可能在程序控制或检测之外 (操作系统、硬件、其它线程等) 被改变时, 应该将该对象声名为 volatile. 关键字 volatile 告诉编译器不应对这样的对象进行优化.
-
volatile 关键字声明的变量, 每次访问时都必须从内存中取出值 (没有被 volatile 修饰的变量, 可能由于编译器的优化, 从 CPU 寄存器中取值).
-
在多个文件之间共享对象.
-
extern "C" 的作用是让 C++ 编译器将 extern "C" 声明的代码当作 C 语言代码处理, 可以避免 C++ 因符号修饰导致代码不能和 C 语言库中的符号进行链接的问题.