Home Char Pointers in C
Post
Cancel

Char Pointers in C

The Code:

I decided to write a quick bit of code to reinforce my understanding of char pointers in C; especially Char** as I recently confused myself. Firstly lets get straight to the code as it is the best way to learn. The code comments should explain what each line is doing however additional explanation of the steps is provided further down the page.

#include <stdio.h>

int main()
{

	char *name = "Bob";
	printf("Name VAL: %p\n", name); //Value of name
	printf("Name PTR: %p\n", &name); //Address of ptr itself
	printf("Name VAL: %s\n\n", name);
	
	char **p_name = &name;
	printf("P_Name VAL: %p\n", p_name); //Address of name ptr
	printf("P_Name PTR: %p\n", &p_name); //Address of ptr itself
	printf("P_Name PTR PTR: %p\n", *p_name); //Derefences to string literal address "Bob"
	printf("P_Name PTR: %s\n\n", *p_name);

	printf("Changed the name pointer to point to John\n");
	name = "John"; //Name ptr now points to new string literal

	printf("P_Name PTR PTR: %p\n", *p_name); //This now derefences to string literal address "John" as p_name points to ptr name
	printf("Name via Pointer: %s\n\n", *p_name);
	
	void *pa = p_name; //Void pointer. Point to value of p_name. Points to address of name ptr
	printf("PA VAL: %p\n", pa); //Address of name ptr
	printf("PA PTR: %p\n\n", &pa); //Address of void ptr itself
	
	//Test deferences pa before passing to test. Test points to the string literal John memory address
	char *test = *((char**)pa); //CAST BEFORE DEREFERENCING
	printf("TEST PTR: %p\n", test); //Address of John. 
	printf("TEST PTR: %s\n\n", test);
	
	
	//Test2 points to the memory address of name ptr
	char **test2 = (char**)pa; //CAST BEFORE DEREFERENCING
	printf("TEST2 PTR PTR: %p\n", test2); //Address of name ptr
	printf("TEST2 PTR PTR: %s\n\n", *test2); //Dereferences to print string literal name is pointing at

	printf("Changed the name pointer to point to Charles\n");
	name = "Charles"; //Name ptr now points to new string literal
	
	//Test deferences pa before passing to test. Test points to the string literal John memory address. No Change
	printf("TEST PTR: %p\n", test); //Address of John. 
	printf("TEST PTR: %s\n\n", test);
	
	
	//Test2 points to the memory address of name ptr
	printf("TEST2 PTR PTR: %p\n", test2); //Address of name ptr
	printf("TEST2 PTR PTR: %s\n\n", *test2); //Dereferences to print string literal name is pointing at. Changes to Charles

	return 0;
}

Diagram:

I have quickly put together a diagram to help visualise how the pointers are interacting with each other in memory.

Steps:

Firstly I have declared a string literal called "Bob" which C stores within an area of memory called "Constant". Line 18 declares the constant string literal and then declares a pointer called "name" which points to the memory address of "Bob". The diagram shows the value of name containing the memory address of "Bob". Printing "name" will print the value of the pointer while "&name" prints the address of the pointer itself.

Line 11 declares a pointer pointer "Char**" and stores the address of the name pointer in its value as shown above. The string literal can be accessed with a single * (Deference), printing with "p_name" will give you the value of "p_name" which is the address of the "name" pointer itself, dereferencing with '*' gets the value of "name" which is "Bob". Next I show how changing the value of "name" to a new string literal called "John" changes the value returned when dereferencing "p_name".

I have shown how a void pointer is declared and cast to a pointer pointer for use elsewhere. This is then used in two different ways; firstly I dereference the void pointer back to the string literal "John". This is fixed and any update to "name" has no effect on "test". Finally I pass "test2" the address of the name pointer and therefore any updates to "name" reflect when dereferencing "test2" as shown when updating "name" to point to "Charles".

Code Output:

The result of the code running will look like this except the memory addresses will be different. The operating system will decide where to store the variables and constants.

Output of the code run showing pointers, values and memory addresses

References:

None although Head First C provides a good explanation of various C topics such as pointers.

This post is licensed under CC BY 4.0 by the author.

If you have found this site useful, please consider buying me a coffee :)

Proud supporter of the Gnome Foundation

Become a Friend of GNOME

Contents

VCentre 6.5 higher memory requirements

NGINX Reverse Proxy LetsEncrypt Auto-Renew

Comments powered by Disqus.