本文定义了一个宏来实现使用new代替realloc的操作,代码如下:
- #include <iostream>
- #include <malloc.h>
- using namespace std;
- // p - 内存指针
- // n - 申请内存数量
- // T - 申请内存类型
- #define RENEW(p, n, T)/
- {/
- T* pNew = new T[n];/
- memcpy(pNew, p, _msize(p));/
- delete[] p;/
- p = pNew;/
- }
- void main(void)
- {
- char* pold = new char[10];
- memset(pold, 0, 10);
- memcpy(pold, "wangliu", 7);
- RENEW(pold, 17, char);
- strcat(pold, "qianggood");
- cout<<pold<<endl;
- delete[] pold;
- /*int* pold = new int[5];
- for (int i = 0; i < 5; i++)
- {
- pold[i] = i;
- }
- RENEW(pold, 10, int);
- for (i = 5; i < 10; i++)
- {
- pold[i] = i;
- }
- for (i = 0; i < 10; i++)
- {
- cout<<pold[i]<<endl;
- }
- delete[] pold;*/
- }
几个问题:
1. 有了malloc/free为什么还要new/delete?
malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符,它们都可用于申请动态内存和释放内存。对于非内部数据类型的对象而言,光用maloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数, 对象在消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。注意new/delete 不是库函数。
2. 上面代码中如果在22行中申请了16长度的内存,则使用delete[] pold;时将出现非法错误,这是由于内存越界造成的,字符串最后面需要'/0'来表示字符串的结尾,所以在第22行应申请17长度的内存。在debug模式下,越界的时候delete会非法操作,但是release模式下不会。因为debug模式下分配内存的时候会多分配4个字节,这4个字节内容是0xFE,delete的时候会检查这4个字节,看是否越界。