The following code uses the & operator to find addresses.
#include <iostream>
using namespace std;
int main() /* w w w .j a va 2s . c o m*/
{
int donuts = 6;
double cups = 4.5;
cout << "donuts value = " << donuts;
cout << " and donuts address = " << &donuts << endl;
cout << "cups value = " << cups;
cout << " and cups address = " << &cups << endl;
return 0;
}
The code above generates the following result.
The name of the pointer represents the location.
Applying the * operator yields the value at the location.
#include <iostream>
int main() /* w w w .j a v a2 s . com*/
{
using namespace std;
int updates = 6; // declare a variable
int * p_updates; // declare pointer to an int
p_updates = &updates; // assign address of int to pointer
// express values two ways
cout << "Values: updates = " << updates;
cout << ", *p_updates = " << *p_updates << endl;
// express address two ways
cout << "Addresses: &updates = " << &updates;
cout << ", p_updates = " << p_updates << endl;
// use pointer to change value
*p_updates = *p_updates + 1;
cout << "Now updates = " << updates << endl;
return 0;
}
The code above generates the following result.
A pointer declaration must specify what type of data to which the pointer points.
For example, the preceding example has this declaration:
int * p_updates;
This states that the combination * p_updates is type int.
The p_updates variable itself must be a pointer.
p_updates points to type int.
The type for p_updates is pointer-to-int or, more concisely, int *.
p_updates is a pointer (an address), and *p_updates is an int and not a pointer.
int* is a type, pointer-to-int.
The following declaration creates one pointer (p1) and one ordinary int (p2):
int* p1, p2;
You need an * for each pointer variable name.
The following code demonstrates how to initialize a pointer to an address.
#include <iostream>
using namespace std;
int main() //w w w . java2 s .co m
{
int higgens = 5;
int * pt = &higgens;
cout << "Value of higgens = " << higgens
<< "; Address of higgens = " << &higgens << endl;
cout << "Value of *pt = " << *pt
<< "; Value of pt = " << pt << endl;
return 0;
}
The code above generates the following result.
The general form for obtaining and assigning memory for a single data object, which can be a structure as well as a fundamental type, is this:
typeName * pointer_name = new typeName;
You use the data type twice: once to specify the kind of memory requested and once to declare a suitable pointer.
#include <iostream>
using namespace std;
int main() /*w ww . j a v a 2 s . c o m*/
{
int nights = 1001;
int * pt = new int; // allocate space for an int
*pt = 1001; // store a value there
cout << "nights value = ";
cout << nights << ": location " << &nights << endl;
cout << "int ";
cout << "value = " << *pt << ": location = " << pt << endl;
double * pd = new double; // allocate space for a double
*pd = 10000001.0; // store a double there
cout << "double ";
cout << "value = " << *pd << ": location = " << pd << endl;
cout << "location of pointer pd: " << &pd << endl;
cout << "size of pt = " << sizeof(pt);
cout << ": size of *pt = " << sizeof(*pt) << endl;
cout << "size of pd = " << sizeof pd;
cout << ": size of *pd = " << sizeof(*pd) << endl;
return 0;
}
The code above generates the following result.
The delete operator enables you to return memory to the memory pool.
You use delete by following it with a pointer to a block of memory originally allocated with new:
int * ps = new int; // allocate memory with new . . . // use the memory delete ps; // free memory with delete when done
This removes the memory to which ps points.
It doesn't remove the pointer ps itself.
You can reuse ps to point to another new allocation.
You should not attempt to free a block of memory that you have previously freed.
It's easy to create a dynamic array in C++; you tell new the type of array element and number of elements you want.
The syntax requires that you follow the type name with the number of elements, in brackets.
For example, if you need an array of 10 ints, you use this:
int * psome = new int [10]; // get a block of 10 ints
The new operator returns the address of the first element of the block.
In this example, that value is assigned to the pointer psome.
Using new with brackets to create an array requires using an alternative form of delete when freeing the array:
delete [] psome; // free a dynamic array
The brackets tells C++ to free the whole array, not just the element pointed to by the pointer.
Here's an example:
int * pt = new int; short * ps = new short [500]; delete [] pt; // effect is undefined, don't do it delete ps; // effect is undefined, don't do it
Don't use delete to free memory that new didn't allocate.
Don't use delete to free the same block of memory twice in succession.
Use delete [] if you used new [] to allocate an array.
Use delete (no brackets) if you used new to allocate a single entity.
The general form for allocating and assigning memory for an array is this:
type_name * pointer_name = new type_name [num_elements];
Example
#include <iostream>
using namespace std;
int main() { /*from w w w . ja v a2 s . com*/
double * p3 = new double [3]; // space for 3 doubles
p3[0] = 0.2; // treat p3 like an array name
p3[1] = 0.5;
p3[2] = 0.8;
cout << "p3[1] is " << p3[1] << ".\n";
p3 = p3 + 1; // increment the pointer
cout << "Now p3[0] is " << p3[0] << " and ";
cout << "p3[1] is " << p3[1] << ".\n";
p3 = p3 - 1; // point back to beginning
delete [] p3; // free the memory
return 0;
}
The code above generates the following result.
C++ interprets the array name as an address.
#include <iostream>
using namespace std;
int main() { //w w w .j av a 2s .c om
double wages[3] = {1.0, 2.0, 3.0};
short stacks[3] = {3, 2, 1};
// two ways to get the address of an array
double * pw = wages; // name of an array = address
short * ps = &stacks[0]; // or use address operator
// with array element
cout << "pw = " << pw << ", *pw = " << *pw << endl;
pw = pw + 1;
//add 1 to the pw pointer
cout << "pw = " << pw << ", *pw = " << *pw << "\n\n";
cout << "ps = " << ps << ", *ps = " << *ps << endl;
ps = ps + 1;
//add 1 to the ps pointer
cout << "ps = " << ps << ", *ps = " << *ps << "\n\n";
//access two elements with array notation
cout << "stacks[0] = " << stacks[0]
<< ", stacks[1] = " << stacks[1] << endl;
//access two elements with pointer notation
cout << "*stacks = " << *stacks
<< ", *(stacks + 1) = " << *(stacks + 1) << endl;
cout << sizeof(wages) << " = size of wages array\n";
cout << sizeof(pw) << " = size of pw pointer\n";
return 0;
}
The code above generates the following result.
The special relationship between arrays and pointers extends to C-style strings. Consider the following code:
char flower[10] = "rose"; cout << flower << "s are red\n";
The name of an array is the address of its first element.
The following code uses two functions from the string library.
The strlen() function returns the length of a string.
The strcpy() function copies a string from one location to another.
#include <iostream>
#include <cstring> // declare strlen(), strcpy()
using namespace std;
/*from w w w . ja v a 2 s. co m*/
int main() {
char animal[20] = "C++"; // animal holds bear
const char * bird = "Java"; // bird holds address of string
char * ps; // uninitialized
cout << animal << " and "; // display bear
cout << bird << "\n"; // display wren
cout << "Enter a kind of animal: ";
cin >> animal; // ok if input < 20 chars
ps = animal; // set ps to point to string
cout << ps << "!\n"; // ok, same as using animal
//Before using strcpy()
cout << animal << " at " << (int *) animal << endl;
cout << ps << " at " << (int *) ps << endl;
ps = new char[strlen(animal) + 1]; // get new storage
strcpy(ps, animal); // copy string to new storage
cout << "After using strcpy():\n";
cout << animal << " at " << (int *) animal << endl;
cout << ps << " at " << (int *) ps << endl;
delete [] ps;
return 0;
}
The code above generates the following result.
The following code uses new to create an unnamed structure and demonstrates both pointer notations for accessing structure members.
#include <iostream>
using namespace std;
struct Product // structure definition
{ //from ww w . jav a 2s .c om
char name[20];
float volume;
double price;
};
int main() {
Product * ps = new Product; // allot memory for structure
cout << "Enter name of Product item: ";
cin.get(ps->name, 20); // method 1 for member access
cout << "Enter volume in cubic feet: ";
cin >> (*ps).volume; // method 2 for member access
cout << "Enter price: $";
cin >> ps->price;
cout << "Name: " << (*ps).name << endl; // method 2
cout << "Volume: " << ps->volume << " cubic feet\n"; // method 1
cout << "Price: $" << ps->price << endl; // method 1
delete ps; // free memory used by structure
return 0;
}
The code above generates the following result.
The following code shows how to use the delete operator.
#include <iostream>
#include <cstring> // or string.h
using namespace std;
char * getname(void); // function prototype
int main() {
char * name; // create pointer but no storage
/*ww w . ja v a 2s . c o m*/
name = getname(); // assign address of string to name
cout << name << " at " << (int *) name << "\n";
delete [] name; // memory freed
name = getname(); // reuse freed memory
cout << name << " at " << (int *) name << "\n";
delete [] name; // memory freed again
return 0;
}
char * getname() // return pointer to new string
{
char temp[80]; // temporary storage
cout << "Enter last name: ";
cin >> temp;
char * pn = new char[strlen(temp) + 1];
strcpy(pn, temp); // copy string into smaller space
return pn; // temp lost when function ends
}
The code above generates the following result.