化工网站建设推广,中国建设银行网站慢,重庆美邦建网站,wordpress开发主题时间到目前为止#xff0c;我们的程序中我们只用了声明变量、数组和其他对象#xff08;objects#xff09;所必需的内存空间#xff0c;这些内存空间的大小都在程序执行之前就已经确定了。但如果我们需要内存大小为一个变量#xff0c;其数值只有在程序运行时 (runtime)才能确… 到目前为止我们的程序中我们只用了声明变量、数组和其他对象objects所必需的内存空间这些内存空间的大小都在程序执行之前就已经确定了。但如果我们需要内存大小为一个变量其数值只有在程序运行时 (runtime)才能确定例如有些情况下我们需要根据用户输入来决定必需的内存空间那么我们该怎么办呢 答案是动态内存分配dynamic memory为此C 集成了操作符new 和delete。 操作符 new 和 delete 是C执行指令。本节后面将会介绍这些操作符在C中的等价命令。 操作符new 和new[ ] 操作符new的存在是为了要求动态内存。new 后面跟一个数据类型并跟一对可选的方括号[ ]里面为要求的元素数。它返回一个指向内存块开始位置的指针。其形式为 pointer new type 或者 pointer new type [elements] 第一个表达式用来给一个单元素的数据类型分配内存。第二个表达式用来给一个数组分配内存。 例如
int * bobby; bobby new int [5];在这个例子里操作系统分配了可存储5个整型int元素的内存空间返回指向这块空间开始位置的指针并将它赋给bobby。因此现在bobby 指向一块可存储5个整型元素的合法的内存空间如下图所示。 你可能会问我们刚才所作的给指针分配内存空间与定义一个普通的数组有什么不同。最重要的不同是数组的长度必须是一个常量这就将它的大小在程序执行之前的设计阶段就被决定了。而采用动态内存分配数组的长度可以常量或变量其值可以在程序执行过程中再确定。 动态内存分配通常由操作系统控制在多任务的环境中它可以被多个应用applications共享因此内存有可能被用光。如果这种情况发生操作系统将不能在遇到操作符new 时分配所需的内存一个无效指针(null pointer)将被返回。因此我们建议在使用new之后总是检查返回的指针是否为空(null)如下例所示
int * bobby; bobby new int [5]; if (bobby NULL) { // error assigning memory. Take measures. };删除操作符delete 既然动态分配的内存只是在程序运行的某一具体阶段才有用那么一旦它不再被需要时就应该被释放以便给后面的内存申请使用。操作符delete 因此而产生它的形式是 delete pointer; 或 delete [ ] pointer; 第一种表达形式用来删除给单个元素分配的内存第二种表达形式用来删除多元素数组的内存分配。在多数编译器中两种表达式等价使用没有区别 虽然它们实际上是两种不同的操作需要考虑操作符重载overloading 我们在后面的section 4.2节中将会看到)。 // rememb-o-matic #include ‹iostream.h› #include ‹stdlib.h› int main ( ) { char input [100]; int i,n; long * l; cout How many numbers do you want to type in? ; cin.getline (input,100); iatoi (input); l new long[i]; if (l NULL) exit (1); for (n0; ni; n) { cout Enter number: ; cin.getline (input,100); l[n]atol (input); } cout You have entered: ; for (n0; ni; n) { cout l[n] , ; delete[] l; return 0; } How many numbers do you want to type in? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32, 这个简单的例子可以记下用户想输入的任意多个数字它的实现归功于我们动态地向系统申请用户要输入的数字所需的空间。 NULL是C库中定义的一个常量专门设计用来指代空指针的。如果这个常量没有被预先定义你可以自己定以它为0: #define NULL 0 在检查指针的时候0和NULL并没有区别。但用NULL 来表示空指针更为常用并且更易懂。原因是指针很少被用来比较大小或被直接赋予一个除0以外的数字常量使用NULL这一赋值行为就被符号化了。 ANSI-C 中的动态内存管理Dynamic memory in ANSI-C 操作符new 和delete 仅在C中有效而在C语言中没有。在C语言中为了动态分配内存我们必须求助于函数库stdlib.h。因为该函数库在C中仍然有效并且在一些现存的程序仍然使用所以我们下面将学习一些关于这个函数库中的函数用法。 函数malloc 这是给指针动态分配内存的通用函数。它的原型是 void * malloc (size_t nbytes); 其中nbytes 是我们想要给指针分配的内存字节数。这个函数返回一个void*类型的指针因此我们需要用类型转换(type cast)来把它转换成目标指针所需要的数据类型例如
char * ronny; ronny (char *) malloc (10);这个例子将一个指向10个字节可用空间的指针赋给ronny。当我们想给一组除char 以外的类型不是1字节长度的的数值分配内存的时候我们需要用元素数乘以每个元素的长度来确定所需内存的大小。幸运的是我们有操作符sizeof它可以返回一个具体数据类型的长度。
int * bobby; bobby (int *) malloc (5 * sizeof(int));这一小段代码将一个指向可存储5个int型整数的内存块的指针赋给bobby它的实际长度可能是 24或更多字节数取决于程序是在什么操作系统下被编译的。 函数calloc calloc 与malloc 在操作上非常相似他们主要的区别是在原型上 void * calloc (size_t nelements, size_t size); 因为它接收2个参数而不是1个。这两个参数相乘被用来计算所需内存块的总长度。通常第一个参数(nelements)是元素的个数第二个参数 (size) 被用来表示每个元素的长度。例如我们可以像下面这样用calloc定义bobby
int * bobby; bobby (int *) calloc (5, sizeof(int));malloc 和calloc的另一点不同在于calloc 会将所有的元素初始化为0。 函数realloc 它被用来改变已经被分配给一个指针的内存的长度。 void * realloc (void * pointer, size_t size); 参数pointer 用来传递一个已经被分配内存的指针或一个空指针而参数size 用来指明新的内存长度。这个函数给指针分配size 字节的内存。这个函数可能需要改变内存块的地址以便能够分配足够的内存来满足新的长度要求。在这种情况下指针当前所指的内存中的数据内容将会被拷贝到新的地址中以保证现存数据不会丢失。函数返回新的指针地址。如果新的内存尺寸不能够被满足函数将会返回一个空指针但原来参数中的指针pointer 及其内容保持不变。 函数 free 这个函数用来释放被前面malloc, calloc 或realloc所分配的内存块。 void free (void * pointer); 注意这个函数只能被用来释放由函数malloc, calloc 和realloc所分配的空间。 你可以参考C reference for cstdlib获得更多关于这些函数的信息。