Memory Allocation
Types of Memory Allocation:
• Static – done at compile time
• Dynamic – get memory during runtime
Stack: Memory Allocated Pop/Push; Local Vars
Heap: Dynamic Allocation of Vars. (malloc)
Stack:
Declare arrays with variables of larger scope
Problem: Only good in the current scope!
float * func(int n)
{
float array[n]; /* good ;scope n */
…
return array; /* severe mistake */
/* Returns ptr to first element; But Stack is now popped !! */
}
malloc
Prototype:
void * malloc (size_t size);
malloc allocates number of bytes specified in size size_t
l Ask for a block of memory
l How big : Of size size
l malloc returns a pointer to that block of memory
l If unsuccessful returns NULL
For example:
float* pFloat = (float *)malloc (sizeof(float));
Release memory: free
Protptype:
void free(void *ptr);
For example:
float * p = (float *)malloc (sizeof(float));
*p = 10.0;
free(p);
New and Delete (used in C++):
For example:
int *p;
p = new int;
delete p;
p = NULL;
delete p;
or, declaration with initialization of the pointer and the pointee:
int * p = new int(5);
is similar to
int* p = new int;
*p = 5;
In this example, p is a pointer to an integer, which is initialized with a value 5.
l Operation new creates an anonymous variable, stored in a region of the memory called the heap, and returns the address of this variable.
l The space has to be freed by a call to the operator delete.
l It is an error if a program deletes a point that does not have memory allocated, or deletes a heap memory twice.
The following example allocates an array of 10 int on the heap and pointer p points to the first member of this array:
int * p = new int[10];
In this case, the size can be a variable determined at run time. This kind of arrays is called dynamic arrays.
To free the memory allocated for a dynamic array, use
delete [ ] p;
If a pointer has a value NULL, operator delete or delete [ ] does nothing, and this is not an error.
So we use delete like this:
delete [ ]p;
p =NULL;
Example :
#include <iostream.h>
int main()
{
char c, *cptr, x;
c = 'A';
cptr = &c; //cptr is assigned the address of c
x = *cptr; // x is assigned the thing to which c is pointing , so x is assigned 'A'
x = c; // same as statement above
return 0;
}
· new and delete replaces C's malloc and free
· new and delete are more aware of dynamic data type and allow constuctors and destructors
Example :
#include <iostream.h>
int main()
{
// examples
int MAX = 10;
int *pint;
pint = new int[MAX];
for (int i=0; i<MAX; i++)
pint[i] = i*i;
for (i=0; i<MAX; i++)
cout << *(pint+i) << endl;
delete [] pint;
return 0;
}
§ 14. Constant 'variables'
A variable can be specified as a constant by the specifier const. A constant variable must be initialized when it is defined. It is not modifiable. 'const' types and the ordinary types are not compatible.
l constant pointers
l pointer to constants
A constant pointer has to be initialized when it is defined, and it cannot be redirected. It can be assigned to an ordinary pointer.
A pointer to constant prevents modification of the pointee through this pointer. A pointer to constant cannot be assigned to an ordinary pointer, but an ordinary pointer can be assigned to a pointer to constant.
Example :
int main( )
{
const int x = 2, y = 3; // two constant integers
int z = 3;
const int *pc = &x; // a pointer to const
int * const cp = &z; // a const pointer
int * pp = &z;
// x = y; // invalid, cannot assign to a const
pc = &z; // OK, pointer to const may point to int
// *pc = 10;
// *pc = y; // invalid, assignment to constant
// *pc = 5; // invalid, assignment to constant
pc = pp; // OK
z = 5; // OK, although it is pointed to by a pointer to constant
z = x; // OK, x is converted to int
*cp = x; // OK, assignment to pointee
// cp = &x; // invalid, redirection of constant pointer
// pp = &x; // invalid, cannot convert const int to int
// pp = pc; // invalid, cannot convert const int to int
pp = cp; // OK, const pointer to int is converted to pointer to int
return 0;
}
l const plays an important role in preventing a member function from re-assigning a pointer passed to it in an argument
练习代码:
#include "stdafx.h"
int main(int argc, char* argv[])
{//定义基本类型的const变量,const位置在那儿都可以
const int x = 2,y = 3;
//定义一个非constbianl
int z = 3;
//定义一个指向常量的指针
const int *pc = &x;
//定义一个常指针
int *const cp = &z;
//定义一个非const指针
int *pp = &z;
z = y;//const变量只能做右值,不能作左值
//x= y;x是const变量,所以x的值 是不可更改的
pc = &z;
//pc是一个指向常量的指针,不能通过该指针去修改指针所指向的内存空间的值,
//但是,该指针可以 指向别的变量
// *pc = 10;//pc是一个指向常量的指针,不能通过该指针去修改指针所指向的内存空间的值,
//但是,该指针可以 指向别的变量
// *pc = y;同上
// *pc = 5;同上
//1. 指向常量的指针,防止通过指针去修改变量的值,而不管该变量是否是const
//2.指向常量的指针,该指针可以指向别的变量,指针的value是可以更改的
//3.指向常量的指针不能赋值给一个普通 的指针
pc = pp;//pc是一个指向常量的指针,pp是一个普通指针
//用一个普通指针给一个指向常量的指针赋值是可以的
pp = pc;//用一个指向常量的指针,赋值给一个普通指针,不可以
//如果可以,那么就可以通过普通 的指针去修改内存的值;
z = 5;给一个非const的变量赋值是可以 的
z= x;用一个const的变量给一个非const变量赋值是可以 的
*cp = x;//通过常指针去修改指针所指向变量的值
// 原则上来讲是可以的。如果指向的变量是const的,那么 不同的编译会有不同的结果
printf("x = %d,y=%d,z = %d\n",x,y,z);
// cp = &x;cp是常指针,所以指针的值不能被修改,给常指针赋值是错误的
// pp = &x;pp是非const指针,给它赋值是可以的。
//pp = pc;指向常量的指针不能赋值给一个普通的指针
pp = cp;//常指针可以赋值给一个普通 指针。
const int *
printf("Hello World!\n");
return 0;
}