Skip to content

Instantly share code, notes, and snippets.

@Theartbug
Created January 18, 2020 00:05
Show Gist options
  • Save Theartbug/5957171a998f9668c1283c354b6e1016 to your computer and use it in GitHub Desktop.
Save Theartbug/5957171a998f9668c1283c354b6e1016 to your computer and use it in GitHub Desktop.
C++ pointers

MOTHER FUCKING POINTERS

general

  • a pointer uniquely identifies some piece of memory in your program
  • allows you fine control of memory usage
  • you can give any value to a pointer, but it will not check if it is valid or exists
    • will turn into a runtime error
  • you must deallocate the memory you allocate for a pointer when you are done with it
  • pointers can have any dataType
  • you should assign NULL to your pointers
    • points to the first location in memory which is 0
    • cannot place anything at this location
  • place the * next to the variable name for clarity
    • int *a, b will only assign a as a pointer
  • when & is used outside of a function argument it will return a memory address
    • can be assigned to a pointer
    • int *ptr = &variable;
    • this is called aliasing since both point to the same place in memory, avoid most times

why pointers

  • for creating dynamic arrays
  • data structures that grow and shrink as the program runs
    • linked lists, trees, graphs

details

  • new keyword creates a place in memory for dynamic memory
    • int *ptr = new int;
  • dereferencing places a value within the memory area that the pointer points to
    • *ptr = 10;
  • deallocate after you are done with memory, must tell the program it is okay to overwrite that area again
    • delete ptr;
    • the variable still exists, and the value it is referenced to still exists
      • DO NOT dereference after deleting!
      • set to variable NULL after deallocation for safety
    • is placed back in heap for reuse
    • local variables (including pointers) are released after function ends
      • does not include dynamic memory release though
    • can reuse the variable though and set a new value in it
      • ptr = new int; *ptr = 4;

allocating arrays dynamically

  • a pointer can point to one item or the first of many
  • arrays start at 0 because you add 0 to the pointer memory address to receive the first value, and add more after that
    • add 1 to get the second value
  • char *name = new char[variable]; how to create a dynamic array
  • delete []char; to clean up
// we still need some size cutoff for input
// but temporarily inside the function!
char temp[100];
char *name;
cin.get(temp, 100, '\n');
cin.ignore(100, '\n');

name = new char[strlen(temp) + 1];
strcpy(name, temp);

// later
...

delete []name;

pointer math

  • accessing array values is the same as adding to the pointer
    • a[5] == *(a+5) == 5[a] == *(5+a)
  • adding to a pointer gets you the next increment of dataType
    • int dataType increments by the size of an int in memory, which is different than a character or boolean
int *a = new int[10];
int *b = new int[10];

for(int i = 0; i < 10; ++i) {
	a[i] = i;
	b[i] = 100*i;
}

// c is the address of the first element of the array a
for(c = a; c < a+10; c++) cout << *c << endl;

// does the exact same thing
for(int i = 0; i < 10; ++i) cout << a[i] << endl;
  • array[i] == *(array + i) == i[array]
char *ptr = new char[6];
strcpy(ptr, "hello");
cout << ptr << endl; // 'hello'
cout << *ptr << endl; // 'h'
cout << *(ptr++) << endl; // 'h' moves pointer over
cout << *ptr << endl; // 'e'
cout << *(++ptr) << endl; // 'l' moves pointer over
cout << ++(*ptr) << endl; // 'm' (updates the value inside of ptr)
cout << ++ptr << endl; // 'lo' moves the pointer over

dynamic structs

  • cannot access pointer struct members with dot notation
    • *ptr.item not allowed (means *(ptr.item))
      • obtain the item, then go to the address that pointer points to (ew)
    • ptr->item or (*ptr).item is how we do it
      • go to the address that ptr points to, then obtain the item
    • this is because * and . have same operator precedence, and c++ reads right to left, so parenthesis are required
  • pointers are their own type
  • -> is the indirect access operator
    • left side must always have the pointer type
    • right side can only be struct or object
    • must NOT be NULL, will become a seg fault

dynamic arrays of structs

  • access the struct / class member with dot notation within the array
product *ptr = new product[size];
// access this way
// does a * operation implicitly
// this is an object, so don't use '->'
ptr[0].item

pointers and functions

  • can pass as an argument to functions via reference or value
    • but careful, can still manipulate a pointer value when passed by value
void inc1(int x) { ++x; }
void inc2(int *x) { ++(*x); x = NULL; } // changes the copy and does not blow up
void inc3(int &x) { ++x; } // similar to inc2
// order of '*' and '&' is IMPORTANT
void inc4(int* &x) { ++(*x); x = NULL; } // will allow you to change the actual value the pointer points to because it was passed by reference

int main() {
	int a = 1;
	int *b = new int;
	*b = 1;

	int1(a) // 1
	int2(&a); // 2 does not change the type of the argument, passes the reference of the value
	int3(a) // 2
	int4(b) // 2 passing in the address of the address

	cout << a << endl;
	cout << *b << endl;
}
  • passing pointer by value is most common
    • requires use of -> with struct / object
  • utilize a temporary array to read input, then use dynamic pointer array to copy user input into
p = new product;
p->item = new char[strlen(tempArray) + 1];
strcpy(p->item, temp);

pointers as members

struct movie {
	char title[100];
	int rating;
}

class list {
	public:
		list();
		list(int);
		// a destructor for clean up (needed for pointers)
		// cannot take any arguments, never manually invoked
		~list();
		int add(const movie&);
		int remove(char title[]);
		int displayAll();
	private:
		movie *myList; // not yet an array, but treating as such
		int moveListSize;
		int numberOfVideos;
}

// in main.cpp
list::list() {
	myList = NULL; // initialize
	movieListSize = 0;
	numberOfVideos = 0;
}
// gives a default value
// will then not need empty constructor
list::list(int size = 100) {
	myList = new movie[size]; // initialize
	movieListSize = size;
	numberOfVideos = 0;
}
list::~list() {
	// clean up!
	// '[]' delete all cells of the array
	// if you forget to do this on an array, will only free up the first position
	delete [] myList;
	// set it to null since it will still point to something, but no longer what we think it does!
	myList = NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment