• C Data Types
  • C Operators
  • C Input and Output
  • C Control Flow
  • C Functions
  • C Preprocessors
  • C File Handling
  • C Cheatsheet
  • C Interview Questions
  • Pointer Arithmetics in C with Examples
  • Applications of Pointers in C
  • Passing Pointers to Functions in C
  • C - Pointer to Pointer (Double Pointer)
  • Chain of Pointers in C with Examples
  • Function Pointer in C
  • How to declare a pointer to a function?
  • Pointer to an Array | Array Pointer
  • Difference between constant pointer, pointers to constant, and constant pointers to constants
  • Pointer vs Array in C
  • NULL Pointer in C
  • Dangling, Void , Null and Wild Pointers in C
  • Near, Far and Huge Pointers in C
  • restrict keyword in C

Pointers are one of the core components of the C programming language. A pointer can be used to store the memory address of other variables, functions, or even other pointers. The use of pointers allows low-level memory access, dynamic memory allocation, and many other functionality in C.

In this article, we will discuss C pointers in detail, their types, uses, advantages, and disadvantages with examples.

What is a Pointer in C?

A pointer is defined as a derived data type that can store the address of other C variables or a memory location. We can access and manipulate the data stored in that memory location using pointers.

As the pointers in C store the memory addresses, their size is independent of the type of data they are pointing to. This size of pointers in C only depends on the system architecture.

Syntax of C Pointers

The syntax of pointers is similar to the variable declaration in C, but we use the ( * ) dereferencing operator in the pointer declaration.

  • ptr is the name of the pointer.
  • datatype is the type of data it is pointing to.

The above syntax is used to define a pointer to a variable. We can also define pointers to functions, structures, etc.

How to Use Pointers?

The use of pointers in C can be divided into three steps:

  • Pointer Declaration
  • Pointer Initialization
  • Pointer Dereferencing

1. Pointer Declaration

In pointer declaration, we only declare the pointer but do not initialize it. To declare a pointer, we use the ( * ) dereference operator before its name.

The pointer declared here will point to some random memory address as it is not initialized. Such pointers are called wild pointers.

2. Pointer Initialization

Pointer initialization is the process where we assign some initial value to the pointer variable. We generally use the ( & ) addressof operator to get the memory address of a variable and then store it in the pointer variable.

We can also declare and initialize the pointer in a single step. This method is called pointer definition as the pointer is declared and initialized at the same time.

Note: It is recommended that the pointers should always be initialized to some value before starting using it. Otherwise, it may lead to number of errors.

3. Pointer Dereferencing

Dereferencing a pointer is the process of accessing the value stored in the memory address specified in the pointer. We use the same ( * ) dereferencing operator that we used in the pointer declaration.

dereferencing a pointer in c

Dereferencing a Pointer in C

C Pointer Example

Types of pointers in c.

Pointers in C can be classified into many different types based on the parameter on which we are defining their types. If we consider the type of variable stored in the memory location pointed by the pointer, then the pointers can be classified into the following types:

1. Integer Pointers

As the name suggests, these are the pointers that point to the integer values.

These pointers are pronounced as Pointer to Integer.

Similarly, a pointer can point to any primitive data type. It can point also point to derived data types such as arrays and user-defined data types such as structures.

2. Array Pointer

Pointers and Array are closely related to each other. Even the array name is the pointer to its first element. They are also known as Pointer to Arrays . We can create a pointer to an array using the given syntax.

Pointer to Arrays exhibits some interesting properties which we discussed later in this article.

3. Structure Pointer

The pointer pointing to the structure type is called Structure Pointer or Pointer to Structure. It can be declared in the same way as we declare the other primitive data types.

In C, structure pointers are used in data structures such as linked lists, trees, etc.

4. Function Pointers

Function pointers point to the functions. They are different from the rest of the pointers in the sense that instead of pointing to the data, they point to the code. Let’s consider a function prototype – int func (int, char) , the function pointer for this function will be

Note: The syntax of the function pointers changes according to the function prototype.

5. Double Pointers

In C language, we can define a pointer that stores the memory address of another pointer. Such pointers are called double-pointers or pointers-to-pointer . Instead of pointing to a data value, they point to another pointer.

Dereferencing Double Pointer

Note: In C, we can create multi-level pointers with any number of levels such as – ***ptr3, ****ptr4, ******ptr5 and so on.

6. NULL Pointer

The Null Pointers are those pointers that do not point to any memory location. They can be created by assigning a NULL value to the pointer. A pointer of any type can be assigned the NULL value.

It is said to be good practice to assign NULL to the pointers currently not in use.

7. Void Pointer

The Void pointers in C are the pointers of type void. It means that they do not have any associated data type. They are also called generic pointers as they can point to any type and can be typecasted to any type.

One of the main properties of void pointers is that they cannot be dereferenced.

8. Wild Pointers

The Wild Pointers are pointers that have not been initialized with something yet. These types of C-pointers can cause problems in our programs and can eventually cause them to crash. If values is updated using wild pointers, they could cause data abort or data corruption.

9. Constant Pointers

In constant pointers, the memory address stored inside the pointer is constant and cannot be modified once it is defined. It will always point to the same memory address.

10. Pointer to Constant

The pointers pointing to a constant value that cannot be modified are called pointers to a constant. Here we can only access the data pointed by the pointer, but cannot modify it. Although, we can change the address stored in the pointer to constant.

Other Types of Pointers in C:

There are also the following types of pointers available to use in C apart from those specified above:

  • Far pointer : A far pointer is typically 32-bit that can access memory outside the current segment.
  • Dangling pointer : A pointer pointing to a memory location that has been deleted (or freed) is called a dangling pointer.
  • Huge pointer : A huge pointer is 32-bit long containing segment address and offset address.
  • Complex pointer: Pointers with multiple levels of indirection.
  • Near pointer : Near pointer is used to store 16-bit addresses means within the current segment on a 16-bit machine.
  • Normalized pointer: It is a 32-bit pointer, which has as much of its value in the segment register as possible.
  • File Pointer: The pointer to a FILE data type is called a stream pointer or a file pointer.

Size of Pointers in C

The size of the pointers in C is equal for every pointer type. The size of the pointer does not depend on the type it is pointing to. It only depends on the operating system and CPU architecture. The size of pointers in C is 

  • 8 bytes for a 64-bit System
  • 4 bytes for a 32-bit System

The reason for the same size is that the pointers store the memory addresses, no matter what type they are. As the space required to store the addresses of the different memory locations is the same, the memory required by one pointer type will be equal to the memory required by other pointer types.

How to find the size of pointers in C?

We can find the size of pointers using the sizeof operator as shown in the following program:

Example: C Program to find the size of different pointer types.

As we can see, no matter what the type of pointer it is, the size of each and every pointer is the same.

Now, one may wonder that if the size of all the pointers is the same, then why do we need to declare the pointer type in the declaration? The type declaration is needed in the pointer for dereferencing and pointer arithmetic purposes.

C Pointer Arithmetic

The Pointer Arithmetic refers to the legal or valid arithmetic operations that can be performed on a pointer. It is slightly different from the ones that we generally use for mathematical calculations as only a limited set of operations can be performed on pointers. These operations include:

  • Increment in a Pointer
  • Decrement in a Pointer
  • Addition of integer to a pointer
  • Subtraction of integer to a pointer
  • Subtracting two pointers of the same type
  • Comparison of pointers of the same type.
  • Assignment of pointers of the same type.

C Pointers and Arrays

In C programming language, pointers and arrays are closely related. An array name acts like a pointer constant. The value of this pointer constant is the address of the first element. For example, if we have an array named val then val and &val[0] can be used interchangeably.

If we assign this value to a non-constant pointer of the same type, then we can access the elements of the array using this pointer.

Example 1: Accessing Array Elements using Pointer with Array Subscript

relationship between array and pointer

Not only that, as the array elements are stored continuously, we can pointer arithmetic operations such as increment, decrement, addition, and subtraction of integers on pointer to move between array elements.

Example 2: Accessing Array Elements using Pointer Arithmetic

accessing array elements using pointer arithmetic

This concept is not limited to the one-dimensional array, we can refer to a multidimensional array element as well using pointers.

To know more about pointers to an array, refer to this article – Pointer to an Array

Uses of Pointers in C

The C pointer is a very powerful tool that is widely used in C programming to perform various useful operations. It is used to achieve the following functionalities in C:

  • Pass Arguments by Reference
  • Accessing Array Elements
  • Return Multiple Values from Function
  • Dynamic Memory Allocation
  • Implementing Data Structures
  • In System-Level Programming where memory addresses are useful.
  • In locating the exact value at some memory location.
  • To avoid compiler confusion for the same variable name.
  • To use in Control Tables.

Advantages of Pointers

Following are the major advantages of pointers in C:

  • Pointers are used for dynamic memory allocation and deallocation.
  • An Array or a structure can be accessed efficiently with pointers
  • Pointers are useful for accessing memory locations.
  • Pointers are used to form complex data structures such as linked lists, graphs, trees, etc.
  • Pointers reduce the length of the program and its execution time as well.

Disadvantages of Pointers

Pointers are vulnerable to errors and have following disadvantages:

  • Memory corruption can occur if an incorrect value is provided to pointers.
  • Pointers are a little bit complex to understand.
  • Pointers are majorly responsible for memory leaks in C .
  • Pointers are comparatively slower than variables in C.
  • Uninitialized pointers might cause a segmentation fault.

In conclusion, pointers in C are very capable tools and provide C language with its distinguishing features, such as low-level memory access, referencing, etc. But as powerful as they are, they should be used with responsibility as they are one of the most vulnerable parts of the language.

FAQs on Pointers in C

Q1. define pointers..

Pointers are the variables that can store the memory address of another variable.

Q2. What is the difference between a constant pointer and a pointer to a constant?

A constant pointer points to the fixed memory location, i.e. we cannot change the memory address stored inside the constant pointer. On the other hand, the pointer to a constant point to the memory with a constant value.

Q3. What is pointer to pointer?

A pointer to a pointer (also known as a double pointer) stores the address of another pointer.

Q4. Does pointer size depends on its type?

No, the pointer size does not depend upon its type. It only depends on the operating system and CPU architecture.

Q5. What are the differences between an array and a pointer?

The following table list the differences between an array and a pointer : Pointer Array A pointer is a derived data type that can store the address of other variables. An array is a homogeneous collection of items of any type such as int, char, etc. Pointers are allocated at run time. Arrays are allocated at runtime. The pointer is a single variable. An array is a collection of variables of the same type. Dynamic in Nature Static in Nature.

Q6. Why do we need to specify the type in the pointer declaration?

Type specification in pointer declaration helps the compiler in dereferencing and pointer arithmetic operations.
  • Quiz on Pointer Basics
  • Quiz on Advanced Pointer

Please Login to comment...

Similar reads.

advertisewithusBannerImg

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Pointer Basics

Section 1 -- pointer rules, 1) pointers and pointees, 2) dereferencing, 3) pointer assignment, section 2 -- binky's code example, java version, c++ version, pascal version, section 3 -- study questions.

  • C++ Language
  • Ascii Codes
  • Boolean Operations
  • Numerical Bases

Introduction

Basics of c++.

  • Structure of a program
  • Variables and types
  • Basic Input/Output

Program structure

  • Statements and flow control
  • Overloads and templates
  • Name visibility

Compound data types

  • Character sequences
  • Dynamic memory
  • Data structures
  • Other data types
  • Classes (I)
  • Classes (II)
  • Special members
  • Friendship and inheritance
  • Polymorphism

Other language features

  • Type conversions
  • Preprocessor directives

Standard library

  • Input/output with files

Address-of operator (&)

definition of pointer assignment

Dereference operator (*)

definition of pointer assignment

  • & is the address-of operator , and can be read simply as "address of"
  • * is the dereference operator , and can be read as "value pointed to by"

Declaring pointers

Pointers and arrays, pointer initialization, pointer arithmetics.

definition of pointer assignment

Pointers and const

Pointers and string literals.

definition of pointer assignment

Pointers to pointers

definition of pointer assignment

  • c is of type char** and a value of 8092
  • *c is of type char* and a value of 7230
  • **c is of type char and a value of 'z'

void pointers

Invalid pointers and null pointers, pointers to functions.

4.3. Pointer Operators

Pointers allow us to work more directly with a computer's memory. Programmers generally don't know (and have no control over) where the compiler and the operating system place variables in memory, so we often think about pointers in general terms. Specifically, when we draw pictures of pointers, we often replace a specific address (a pointer variable's contents) with an arrow: The arrow points to the data whose address the pointer stores. Although we can't control a variable's placement in memory, we can find its address with one of the pointer operators and save it in a pointer variable. Once we have the variable's address, we can work with it indirectly through the pointer.

Although we can use many operators with pointers, six are common. C++ forms two of them as complete words: new and delete ; one operator consists of two characters without any spaces: -> , and the remaining three operators consist of a single character. Unfortunately, there are a limited number of characters on a keyboard, and all the symbols used to implement the single-character pointer operators have other overloaded meanings. The compiler distinguishes between the meanings based on context (i.e., where the symbols appear in a program). For example, the ampersand, & , forms the address of operator. Recall from the previous chapter that two adjacent ampersands form the logical-AND operator. Furthermore, the chapter 2 supplemental section introduces the single ampersand operator as the bitwise-AND operator . To make matters worse, besides its use as the multiplication operator, the asterisk, * , has two uses just within the context of pointers. First, it defines a pointer variable, and second, it serves as the dereference or the indirection operator (both name the same operation), which we take up in greater detail in the next section.

The following figure demonstrates two operations with pointers. It illustrates defining a pointer variable, p , and how to find the address of an existing variable, i . The address-of-operator may be used with any variable regardless of its type. The demonstration uses the integer variable i for simplicity. Subsequent sections in this chapter describe the other operators.

  • Defines variables i and p . In this context, the asterisk defines p as a pointer variable, specifically, a variable that holds the address of an integer. The compiler allocates memory to hold the variables and maps their names to those memory locations. Both variables have an address, but the contents are undefined. When defining a pointer variable, there may be a space on either or both sides of the asterisk: int* p; , int *p; , or int * p; .
  • Initializes both variables. The content of the variables changes, but their addresses remain the same. The ampersand is the address-of operator ; it forms an expression with the variable immediately to its right that calculates the address of the variable. p and &i are assignment compatible because both sides of the assignment operator represent an address; that is, the assignment operation is possible because pointers are variables that store addresses.
  • An alternate view of (b): For the sake of illustrating what is taking place in memory, the address stored in p is replaced by an arrow pointing from p to i . When using a picture to understand or solve a problem that uses pointers, it is very common to represent the value stored in a pointer variable as an arrow from the pointer variable to the data it points to or refers to.

Many of the C++ operators introduced in previous chapters will "work" with pointers in the sense that they will compile and run without errors. However, not all operators produce meaningful or useful results when applied to pointers. If you recall how pointers "look," you can get a good sense of how or if most operators work with them.

  • A program can define and initialize a pointer in two ways.
  • An abstract representation of the relation between a pointer and the data it points to.
  • Assignment : pointer variables store the address of some data. When a statement operation assigns one pointer to another, it copies the address saved in the right-hand pointer to the left-hand pointer.
  • Pointer assignment results in two pointers pointing to the same data. The assignment operation does not copy the data.
  • sizeof forms an expression that is the size, measured in bytes, of the argument. When applied to a pointer variable, it returns the size of the pointer, not the size of the data to which it points.
  • sizeof(p) > sizeof(char)
  • sizeof(p) = sizeof(int)
  • sizeof(p) < sizeof(big_class)

We have, so far, only focused on the behavior of the pointer operators without considering why we might want to use them in a real-world program. We take this approach because pointers are a new concept to most of you, and I believe it is easier to introduce them without the distraction of a problem. However, it is challenging to appreciate the value of pointers without demonstrating their use. We will see some legitimate uses for pointers later in this chapter and throughout the text. But, before we see those examples, we must explore the indirection or dereference operator, the most challenging pointer operator to understand.

DEV Community

DEV Community

AbdulKarim

Posted on Oct 29, 2023

How C-Pointers Works: A Step-by-Step Beginner's Tutorial

In this comprehensive C Pointers tutorial, my primary goal is to guide you through the fundamentals of C pointers from the ground up. By the end of this tutorial, you will have gained an in-depth understanding of the following fundamental topics:

  • What is a Pointer?
  • How Data is Stored in Memory?
  • Storing Memory Addresses using Pointers

Accessing Data through Pointers

  • Pointer Arithmetic
  • Pointer to Pointer (Double Pointers)
  • Passing Pointers as Function Arguments

Arrays of Pointers

Null pointers, prerequisite:.

To grasp pointers effectively, you should be comfortable with basic C programming concepts, including variables, data types, functions, loops, and conditional statements. This familiarity with C programming forms the foundation for understanding how pointers work within the language. Once you have a solid grasp of these fundamental concepts, you can confidently delve into the intricacies of C pointers.

What is a pointer?

A pointer serves as a reference that holds the memory location of another variable. This memory address allows us to access the value stored at that location in the memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory

Pointers can be a challenging concept for beginners to grasp, but in this tutorial, I'll explain them using real-life analogies to make the concept clearer. However, Before delving into pointers and their workings, it's important to understand the concept of a memory address.

A memory address is a unique identifier that points to a specific location in a computer's memory. Think of it like a street address for data stored in your computer's RAM (Random Access Memory). Just as a street address tells you where a particular house is located in the physical world, a memory address tells the computer where a specific piece of information or data is stored in its memory.

Take a look at the image below for a better understanding:

Block of memory

In this illustration, each block represents one byte of memory. It's important to note that every byte of memory has a unique address. To make it easier to understand, I've represented the addresses in decimal notation, but computers actually store these addresses using hexadecimal values. Hexadecimal is a base-16 numbering system commonly used in computing to represent memory addresses and other low-level data. It's essential to be aware of this representation when working with memory-related concepts in computer programming

How data is stored in the memory:

Every piece of data in your computer, whether it's a number, a character, or a program instruction, is stored at a specific memory address. The amount of space reserved for each data type can vary, and it is typically measured in bytes (where 1 byte equals 8 bits, with each bit representing either 0 or 1). The specific sizes of data types also depend on the computer architecture you are using. For instance, on most 64-bit Linux machines, you'll find the following typical sizes for common data types: char = 1 byte int = 4 bytes float = 4 bytes double = 8 bytes These sizes define how much memory each data type occupies and are crucial for memory management and efficient data representation in computer systems.

You can use the sizeof operator to determine the size of data types on your computer. example:

In this example: sizeof(char) returns the size of the char data type in bytes. sizeof(int) returns the size of the int data type in bytes. sizeof(float) returns the size of the float data type in bytes. sizeof(double) returns the size of the double data type in bytes. When you run this code, it will print the sizes of these data types on your specific computer, allowing you to see the actual sizes used by your system.

When you declare a variable, the computer allocates a specific amount of memory space corresponding to the chosen data type. For instance, when you declare a variable of type char, the computer reserves 1 byte of memory because the size of the 'char' data type is conventionally 1 byte.

address of char n

In this example, we declare a variable n of type char without assigning it a specific value. The memory address allocated for the n variable is 106 . This address, 106 , is where the computer will store the char variable n, but since we haven't assigned it a value yet, the content of this memory location may initially contain an unpredictable or uninitialized value.

When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n. When we assign the value 'C' to the variable n, the character 'C' is stored in the memory location associated with the variable n.

address of cahr n = c

As mentioned earlier, a byte can only store numerical values. When we store the letter 'C' in a byte, the byte actually holds the ASCII code for 'C,' which is 67. In computer memory, characters are represented using their corresponding ASCII codes. So, in memory, the character 'C' is stored as the numerical value 67. Here's how it looks in memory

Ascii code of c

Since integers are typically stored within four bytes of memory, let's consider the same example with an int variable. In this scenario, the memory structure would appear as follows:

add. of int t

In this example, the memory address where the variable t is stored is 121. An int variable like “t” typically uses four consecutive memory addresses, such as 121, 122, 123, and 124. The starting address, in this case, 121, represents the location of the first byte of the int, and the subsequent addresses sequentially represent the following bytes that collectively store the complete int value.

If you want to know the memory address of a variable in a program, you can use the 'address of' unary operator, often denoted as the '&' operator. This operator allows you to access the specific memory location where a variable is stored.

When you run the following program on your computer: It will provide you with specific memory addresses for the variables c and n. However, each time you rerun the program, it might allocate new memory addresses for these variables. It's important to understand that while you can determine the memory address of a variable using the & operator, the exact memory location where a variable is stored is typically managed by the system and the compiler. As a programmer, you cannot directly control or assign a specific memory location for a variable. Instead, memory allocation and management are tasks handled by the system and the compiler.

Storing memory address using pointers

As mentioned earlier, a pointer is a variable that stores the memory address of another variable. This memory address allows us to access the value stored at that location in memory. You can think of a pointer as a way to reference or point to the location where data is stored in your computer's memory.

Now, let's begin by declaring and initializing pointers. This step is essential because it sets up the pointer to hold a specific memory address, enabling us to interact with the data stored at that location.

Declaring Pointers: To declare a pointer, you specify the data type it points to, followed by an asterisk (*), and then the pointer's name. For example:

Here, we've declared a pointer named ptr that can point to integers.

Memory of Declaring an integer pointer

The size of pointers on 64-bit systems is usually 8 bytes (64 bits). To determine the pointer size on your system, you can use the sizeof operator:

Initializing Pointers: Once you've declared a pointer, you typically initialize it with the memory address it should point to. Once again, To obtain the memory address of a variable, you can employ the address-of operator (&). For instance:

In this program:

We declare an integer variable x and initialize it with the value 10. This line creates a variable x in memory and assigns the value 10 to it.

ptr

We declare an integer pointer ptr using the int *ptr syntax. This line tells the compiler that ptr will be used to store the memory address of an integer variable.

pointrt to ptr

We initialize the pointer ptr with the memory address of the variable x . This is achieved with the line ptr = &x; . The & operator retrieves the memory address of x, and this address is stored in the pointer ptr .

address of variable x

Dereferencing Pointers: To access the data that a pointer is pointing to, you need to dereference the pointer. Dereferencing a pointer means accessing the value stored at the memory address that the pointer points to. In C, you can think of pointers as variables that store memory addresses rather than actual values. To get the actual value (data) stored at that memory address, you need to dereference the pointer.

Dereferencing is done using the asterisk (*) operator. Here's an example:

It looks like this in the memory: int x = 10; variable 'x' stores the value 10:

var X

int *ptr = &x; Now, the pointer 'ptr' point to the address of 'x':

Pointer to X

int value = *ptr; Dereference 'ptr' to get the value stored at the address it points to:

pointer value is 10

Reading and Modifying Data: Pointers allow you to not only read but also modify data indirectly:

Note: The asterisk is a versatile symbol with different meanings depending on where it's used in your C program, for example: Declaration: When used during variable declaration, the asterisk (*) indicates that a variable is a pointer to a specific data type. For example: int *ptr; declares 'ptr' as a pointer to an integer.

Dereferencing: Inside your code, the asterisk (*) in front of a pointer variable is used to access the value stored at the memory address pointed to by the pointer. For example: int value = *ptr; retrieves the value at the address 'ptr' points to.

Pointer Arithmetic:

Pointer arithmetic is the practice of performing mathematical operations on pointers in C. This allows you to navigate through arrays, structures, and dynamically allocated memory. You can increment or decrement pointers, add or subtract integers from them, and compare them. It's a powerful tool for efficient data manipulation, but it should be used carefully to avoid memory-related issues.

Incrementing a Pointer:

Now, this program is how it looks in the memory: int arr[4] = {10, 20, 30, 40};

int arr

This behavior is a key aspect of pointer arithmetic. When you add an integer to a pointer, it moves to the memory location of the element at the specified index, allowing you to efficiently access and manipulate elements within the array. It's worth noting that you can use pointer arithmetic to access elements in any position within the array, making it a powerful technique for working with arrays of data. Now, let's print the memory addresses of the elements in the array from our previous program.

If you observe the last two digits of the first address is 40, and the second one is 44. You might be wondering why it's not 40 and 41. This is because we're working with an integer array, and in most systems, the size of an int data type is 4 bytes. Therefore, the addresses are incremented in steps of 4. The first address shows 40, the second 44, and the third one 48

Decrementing a Pointer Decrement (--) a pointer variable, which makes it point to the previous element in an array. For example, ptr-- moves it to the previous one. For example:

Explanation:

We have an integer array arr with 5 elements, and we initialize a pointer ptr to point to the fourth element (value 40) using &arr[3].

Then, we decrement the pointer ptr by one with the statement ptr--. This moves the pointer to the previous memory location, which now points to the third element (value 30).

Finally, we print the value pointed to by the decremented pointer using *ptr, which gives us the value 30.

In this program, we demonstrate how decrementing a pointer moves it to the previous memory location in the array, allowing you to access and manipulate the previous element.

Pointer to pointer

Pointers to pointers, or double pointers, are variables that store the address of another pointer. In essence, they add another level of indirection. These are commonly used when you need to modify the pointer itself or work with multi-dimensional arrays.

To declare and initialize a pointer to a pointer, you need to add an extra asterisk (*) compared to a regular pointer. Let's go through an example:

In this example, ptr2 is a pointer to a pointer. It points to the memory location where the address of x is stored (which is ptr1 ).

pointer to poiter

The below program will show you how to print the value of x through pointer to pointer

In this program, we first explain that it prints the value of x using a regular variable, a pointer, and a pointer to a pointer. We then print the memory addresses of x , ptr1 , and ptr2 .

Passing Pointers as Function Arguments:

In C, you can pass pointers as function arguments. This allows you to manipulate the original data directly, as opposed to working with a copy of the data, as you would with regular variables. Here's how it works:

How to Declare and Define Functions that Take Pointer Arguments: In your function declaration and definition, you specify that you're passing a pointer by using the * operator after the data type. For example:

In the above function, we declare ptr as a pointer to an integer. This means it can store the memory address of an integer variable.

Why Would You Pass Pointers to Functions?

Passing pointers to functions allows you to:

  • Modify the original data directly within the function.
  • Avoid making a copy of the data, which can be more memory-efficient.
  • Share data between different parts of your program efficiently.

This concept is especially important when working with large data structures or when you need to return multiple values from a function.

Call by Value vs. Call by Reference:

Understanding how data is passed to functions is crucial when working with pointers. there are two common ways that data can be passed to functions: call by value and call by reference.

Call by Value:

When you pass data by value, a copy of the original data is created inside the function. Any modifications to this copy do not affect the original data outside of the function. This is the default behavior for most data types when you don't use pointers.

Call by Reference (Using Pointers):

When you pass data by reference, you're actually passing a pointer to the original data's memory location. This means any changes made within the function will directly affect the original data outside the function. This is achieved by passing pointers as function arguments, making it call by reference. Using pointers as function arguments allows you to achieve call by reference behavior, which is particularly useful when you want to modify the original data inside a function and have those changes reflected outside the function.

Let's dive into some code examples to illustrate how pointers work as function arguments. We'll start with a simple example to demonstrate passing a pointer to a function and modifying the original data.

Consider this example:

In this code, we define a function modifyValue that takes a pointer to an integer. We pass the address of the variable num to this function, and it doubles the value stored in num directly.

This is a simple demonstration of passing a pointer to modify a variable's value. Pointers allow you to work with the original data efficiently.

An array of pointers is essentially an array where each element is a pointer. These pointers can point to different data types (int, char, etc.), providing flexibility and efficiency in managing memory.

How to Declare an Array of Pointers? To declare an array of pointers, you specify the type of data the pointers will point to, followed by square brackets to indicate it's an array, and then the variable name. For example:

Initializing an Array of Pointers You can initialize an array of pointers to each element to point to a specific value, For example:

How to Access Elements Through an Array of Pointers? To access elements through an array of pointers, you can use the pointer notation. For example:

This program demonstrates how to access and print the values pointed to by the pointers in the array.

A NULL pointer is a pointer that lacks a reference to a valid memory location. It's typically used to indicate that a pointer doesn't have a specific memory address assigned, often serving as a placeholder or default value for pointers.

Here's a code example that demonstrates the use of a NULL pointer:

In this example, we declare a pointer ptr and explicitly initialize it with the value NULL. We then use an if statement to check if the pointer is NULL. Since it is, the program will print "The pointer is NULL." This illustrates how NULL pointers are commonly used to check if a pointer has been initialized or assigned a valid memory address.

conclusion:

You've embarked on a comprehensive journey through the intricacies of C pointers. You've learned how pointers store memory addresses, enable data access, facilitate pointer arithmetic, and how they can be used with arrays and functions. Additionally, you've explored the significance of NULL pointers.

By completing this tutorial, you've equipped yourself with a robust understanding of pointers in C. You can now confidently navigate memory, manipulate data efficiently, and harness the power of pointers in your programming projects. These skills will be invaluable as you advance in your coding endeavors. Congratulations on your accomplishment, and keep coding with confidence!

Reference: C - Pointers - Tutorials Point

Pointers in C: A One-Stop Solution for Using C Pointers - simplilearn

Top comments (3)

pic

Templates let you quickly answer FAQs or store snippets for re-use.

imperiald profile image

  • Joined Jan 7, 2024

Love your way to write articles, could you add an article for, .o files, .h files, lists and makefile? Thank you in advance!

cocomelonjuice profile image

  • Joined Nov 4, 2023

Great post. Thank you so much for this.

koderkareem profile image

Thank you for your kind words! I'm thrilled to hear that you enjoyed the article. Your feedback means a lot to me. If you have any questions or if there's a specific topic you'd like to see in future posts, feel free to let me know. Thanks again for your support

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink .

Hide child comments as well

For further actions, you may consider blocking this person and/or reporting abuse

arbythecoder profile image

Automate Your Infrastructure with Terraform: A Beginner's Guide

Arbythecoder - Apr 23

stephrp12 profile image

What Will You Choose?

StephRP12 - Apr 10

allyn profile image

allyn - Apr 14

emmabase profile image

How to Implement pagination on API Endpoint Using Nodejs and TypeScript

Emmanuel Eneche - Apr 22

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Learn C practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn c interactively, introduction.

  • Getting Started with C
  • Your First C Program
  • C Variables, Constants and Literals
  • C Data Types
  • C Input Output (I/O)
  • C Programming Operators

Flow Control

  • C if...else Statement
  • C while and do...while Loop
  • C break and continue
  • C switch Statement
  • C goto Statement
  • C Functions
  • C User-defined functions
  • Types of User-defined Functions in C Programming
  • C Recursion
  • C Storage Class

Programming Arrays

  • C Multidimensional Arrays
  • Pass arrays to a function in C

Programming Pointers

Relationship Between Arrays and Pointers

C Pass Addresses and Pointers

C Dynamic Memory Allocation

  • C Array and Pointer Examples

Programming Strings

  • C Programming Strings
  • String Manipulations In C Programming Using Library Functions
  • String Examples in C Programming

Structure and Union

C structs and Pointers

  • C Structure and Function

Programmimg Files

  • C File Handling
  • C Files Examples

Additional Topics

  • C Keywords and Identifiers
  • C Precedence And Associativity Of Operators
  • C Bitwise Operators
  • C Preprocessor and Macros
  • C Standard Library Functions
  • Access Array Elements Using Pointer

Pointers are powerful features of C and C++ programming. Before we learn pointers, let's learn about addresses in C programming.

  • Address in C

If you have a variable var in your program, &var will give you its address in the memory.

We have used address numerous times while using the scanf() function.

Here, the value entered by the user is stored in the address of var variable. Let's take a working example.

Note: You will probably get a different address when you run the above code.

Pointers (pointer variables) are special variables that are used to store addresses rather than values.

Pointer Syntax

Here is how we can declare pointers.

Here, we have declared a pointer p of int type.

You can also declare pointers in these ways.

Let's take another example of declaring pointers.

Here, we have declared a pointer p1 and a normal variable p2 .

  • Assigning addresses to Pointers

Let's take an example.

Here, 5 is assigned to the c variable. And, the address of c is assigned to the pc pointer.

Get Value of Thing Pointed by Pointers

To get the value of the thing pointed by the pointers, we use the * operator. For example:

Here, the address of c is assigned to the pc pointer. To get the value stored in that address, we used *pc .

Note: In the above example, pc is a pointer, not *pc . You cannot and should not do something like *pc = &c ;

By the way, * is called the dereference operator (when working with pointers). It operates on a pointer and gives the value stored in that pointer.

  • Changing Value Pointed by Pointers

We have assigned the address of c to the pc pointer.

Then, we changed the value of c to 1. Since pc and the address of c is the same, *pc gives us 1.

Let's take another example.

Then, we changed *pc to 1 using *pc = 1; . Since pc and the address of c is the same, c will be equal to 1.

Let's take one more example.

Initially, the address of c is assigned to the pc pointer using pc = &c; . Since c is 5, *pc gives us 5.

Then, the address of d is assigned to the pc pointer using pc = &d; . Since d is -15, *pc gives us -15.

  • Example: Working of Pointers

Let's take a working example.

Explanation of the program

A pointer variable and a normal variable is created.

Common mistakes when working with pointers

Suppose, you want pointer pc to point to the address of c . Then,

Here's an example of pointer syntax beginners often find confusing.

Why didn't we get an error when using int *p = &c; ?

It's because

is equivalent to

In both cases, we are creating a pointer p (not *p ) and assigning &c to it.

To avoid this confusion, we can use the statement like this:

Now you know what pointers are, you will learn how pointers are related to arrays in the next tutorial.

Table of Contents

  • What is a pointer?
  • Common Mistakes

Sorry about that.

Related Tutorials

Learn C++

12.9 — Pointers and const

Consider the following code snippet:

With normal (non-const) pointers, we can change both what the pointer is pointing at (by assigning the pointer a new address to hold) or change the value at the address being held (by assigning a new value to the dereferenced pointer).

However, what happens if the value we want to point at is const?

The above snippet won’t compile -- we can’t set a normal pointer to point at a const variable. This makes sense: a const variable is one whose value cannot be changed. Allowing the programmer to set a non-const pointer to a const value would allow the programmer to dereference the pointer and change the value. That would violate the const-ness of the variable.

Pointer to const value

A pointer to a const value (sometimes called a pointer to const for short) is a (non-const) pointer that points to a constant value.

To declare a pointer to a const value, use the const keyword before the pointer’s data type:

In the above example, ptr points to a const int . Because the data type being pointed to is const, the value being pointed to can’t be changed.

However, because a pointer to const is not const itself (it just points to a const value), we can change what the pointer is pointing at by assigning the pointer a new address:

Just like a reference to const, a pointer to const can point to non-const variables too. A pointer to const treats the value being pointed to as constant, regardless of whether the object at that address was initially defined as const or not:

Const pointers

We can also make a pointer itself constant. A const pointer is a pointer whose address can not be changed after initialization.

To declare a const pointer, use the const keyword after the asterisk in the pointer declaration:

In the above case, ptr is a const pointer to a (non-const) int value.

Just like a normal const variable, a const pointer must be initialized upon definition, and this value can’t be changed via assignment:

However, because the value being pointed to is non-const, it is possible to change the value being pointed to via dereferencing the const pointer:

Const pointer to a const value

Finally, it is possible to declare a const pointer to a const value by using the const keyword both before the type and after the asterisk:

A const pointer to a const value can not have its address changed, nor can the value it is pointing to be changed through the pointer. It can only be dereferenced to get the value it is pointing at.

Pointer and const recap

To summarize, you only need to remember 4 rules, and they are pretty logical:

  • A non-const pointer can be assigned another address to change what it is pointing at.
  • A const pointer always points to the same address, and this address can not be changed.
  • A pointer to a non-const value can change the value it is pointing to. These can not point to a const value.
  • A pointer to a const value treats the value as const when accessed through the pointer, and thus can not change the value it is pointing to. These can be pointed to const or non-const l-values (but not r-values, which don’t have an address).

Keeping the declaration syntax straight can be a bit challenging:

  • A const before the asterisk is associated with the type being pointed to. Therefore, this is a pointer to a const value, and the value cannot be modified through the pointer.
  • A const after the asterisk is associated with the pointer itself. Therefore, this pointer cannot be assigned a new address.

guest

Intro to C for CS31 Students

Part 2: structs & pointers.

  • Pointers and Functions C style "pass by referece"
  • Dynamic Memory Allocation (malloc and free)
  • Pointers to Structs

Defining a struct type

Declaring variables of struct types, accessing field values, passing structs to functions, rules for using pointer variables.

  • Next, initialize the pointer variable (make it point to something). Pointer variables store addresses . Initialize a pointer to the address of a storage location of the type to which it points. One way to do this is to use the ampersand operator on regular variable to get its address value: int x; char ch; ptr = &x; // ptr get the address of x, pointer "points to" x ------------ ------ ptr | addr of x|--------->| ?? | x ------------ ------ cptr = &ch; // ptr get the address of ch, pointer "points to" ch cptr = &x; // ERROR! cptr can hold a char address only (it's NOT a pointer to an int) All pointer variable can be set to a special value NULL . NULL is not a valid address but it is useful for testing a pointer variable to see if it points to a valid memory address before we access what it points to: ptr = NULL; ------ ------ cptr = NULL; ptr | NULL |-----| cptr | NULL |----| ------ ------
  • Use *var_name to dereference the pointer to access the value in the location that it points to. Some examples: int *ptr1, *ptr2, x, y; x = 8; ptr1 = NULL; ptr2 = &x; ------------ ------ ptr2 | addr of x|--------->| 8 | x ------------ ------ *ptr2 = 10; // dereference ptr2: "what ptr2 points to gets 10" ------------ ----- ptr2 | addr of x|--------->| 10 | x ------------ ----- y = *ptr2 + 3; // dereference ptr2: "y gets what ptr2 points to plus 3" ----- ----- ptr1 = ptr2; // ptr1 gets address value stored in ptr2 ------------ ----- ptr2 | addr of x |--------->| 10 | x ------------ ----- /\ ------------ | ptr1 | addr of x |-------------- ------------ // TODO: finish tracing through this code and show what is printed *ptr1 = 100; ptr1 = &y; *ptr1 = 80; printf("x = %d y = %d\n", x, y); printf("x = %d y = %d\n", *ptr2, *ptr1);
  • and what does this mean with respect to the value of each argument after the call?
  • Implement a program with a swap function that swaps the values stored in its two arguments. Make some calls to it in main to test it out.

malloc and free

Pointers, the heap, and functions, linked lists in c.

Get an introduction to pointers and memory drawings. Learn about pointer usage, operators, and reading pointer declarations.

Introduction

Why pointers, address-of operator, dereference, other operations with pointers, the null pointer, reading pointer declarations.

While working with variables, we choose different types for them, depending on what kind of data we want to store.

For example:

  • To store 5 , we typically use an int variable.
  • To store 3.5 , we use a double variable.
  • To store a , we use a char variable.

Well, we can view pointers as a different data type. They don’t store a number or a character. Pointers hold a reference to another variable or the address of another variable.

The address of a variable is the point in memory where the operating system decided to place it or the address of the box where we put that variable.

To create a pointer, we can use type* ptr . In other words, add an asterisk * to the regular variable declaration.

To create a variable of type pointer to an integer (a pointer variable that can point to an integer), we can use the following syntax:

Pointers are like regular variables and are stored inside a box in memory. The only difference is that they don’t hold value in the traditional sense. Pointers store a reference to another variable or the address of a variable. Check the following image:

This sort of indirection may feel weird at first, but imagine we want to go to our new friend’s house:

  • It’s our first visit so we’re not sure how to get there.
  • We start asking people on the street, and they point us to our friend’s address.
  • At our friend’s house address, we find our friend.
  • Pointers work in the same way.
  • They point (like the people on the street) to the memory location (house in our example), or address of a variable.
  • We know that by following the pointer and reaching that address, we’ll be able to interact with the variable.

One could ask: “Well, I already know the variable because I created it. Can I just use it directly and not deal with pointers?”. Good question!

Pointers solve a few issues, such as:

  • Sharing data between multiple functions. We can do it by copying the data several times, but this can become inefficient. Pointers allow us to pass a reference to our data. No copy to perform!
  • Creating data structures like lists, trees, matrices, graphs, etc. They have a linked internal structure, which pointers can easily represent.
  • Writing shorter and modular code that is more resistant to change.
  • Allowing us to implement genericity in C.

These points are more complex than they would seem at first glance, and we’ll explore them in depth during this course.

Let’s look at how we can create a pointer and how to point it to another variable. We need to introduce the following operators:

  • * (dereference operator)
  • & (address-of operator)

The & operator is called the address-of operator and is used to find out or get the address of a variable, for example, to get the memory location of the box where that variable is stored.

The syntax is &variable .

Let’s use this operator to retrieve the addresses of two variables- i and j .

Wow! The output is scary. What even is that!?

The boxes or bytes inside the memory are indexed or numbered. Their address is a number, starting from 0 and going up depending on how much memory the system has. The operating system reserves some memory areas. While writing code, it’s unlikely we’ll get a small address like 0, 5, or 1000. But regardless, they are still numbers.

Check the memory snapshot below, it shows a few bytes and their addresses/indexes.

Now, look at the output for the address of variable i . Assume it is 0x7ffdee2428ec (it can be different if we run the code multiple times), and while scary, it’s just a number written in base 16 or hexadecimal system. We learned that computers store data in base 2. However, the convention for displaying or working with memory addresses is to do it in base 16.

The %p specifier we used inside printf prints the address in hex. We can convert the number to base ten and obtain 0x7ffdee2428ec = 140728598800620 . It’s not mandatory to use hex, but this is the usual practice.

In base 16, we use 0–9, and A–F (see the next table). In other words, we use all the numbers lesser than 16, which is the base of the hexadecimal number system.

Hexadecimal system

We don’t need to know how to convert from or to base 16 but that an address is a number that uniquely identifies a box or starting memory location of a variable.

Now that we know how to get the address of a variable, we can write a pointer to it.

Printing i and j gives us the values we put inside the variables.

Printing &i and &j gives us the memory addresses of the i and j variables.

Printing intPtr1 and intPtr2 gives us the address of the variables that the pointers point to. Notice that the address of i is the same as intPtr1 because the pointer stores the address of the variable i .

Now that we have a pointer to a variable, we may want to be able to read/write that variable using it. To do that, we need to use the dereference operator * with the following syntax:

Let’s see an example:

In line 11 , we print the value of i using the pointer by dereferencing it.

In line 12 , we change the value stored inside i using the pointer by dereferencing it.

Check the following memory drawing, where intPtr points to the i variable.

We can reassign pointers and make them point to something else (if they are not constant). A constant pointer uses the const keyword with the same meaning as for variables.

Pointers support the assignment operation. Assigning a pointer variable to another makes both pointers point to the same variable. The variables are not affected in any way.

Consider the following code:

Notice that both pointers hold the same memory address and refer to x (declared at line 6 ). We reassigned ptr2 to point to the same thing as ptr1 .

The code is equivalent to the following:

What happens when we create a pointer without initializing it?

Where does intPtr point? It gets initialized with garbage (whatever random values were in the memory location of intPtr previously) and does not point to somewhere valid. Attempting to work with such a pointer leads to undefined behavior (it may work one time, and crash another time, depending on what was in the memory) and hard-to-track bugs!

To test if we set the pointer to something or not, we can use a constant value called NULL (usually defined as 0). Here, NULL means a pointer points nowhere, but the advantage is that we can check against NULL and avoid dereferencing an invalid pointer.

Let’s see an example code. In the code below, we create three pointers— intPtr , anotherPtr , and lastPtr . Then, we explore the consequences of leaving them uninitialized, setting them to NULL and a valid memory address.

We’ll see intPtr is very dangerous, and we have no way of knowing it is uninitialized.

The anotherPtr pointer is invalid, but it is NULL . We can guard against dereferencing it with an if check.

The lastPtr pointer contains a valid memory address and everything works fine.

Please follow the comments inside the code to find out the differences:

Note: Always assign pointers to NULL when not setting a valid address immediately.

The intPtr pointer is a (wild) pointer, it doesn’t contain a valid address, and it’s not NULL either.

A basic pointer declaration is pretty straightforward, but what happens when we introduce more keywords?

What are ptr1 , ptr2 , ptr3 , and ptr4 ? Is the pointer constant? Or the variables? Or both? Is ptr3 a const pointer, or does it point to a const variable?

A nice trick is to read pointer declarations from right to left.

  • ptr1 is a pointer ( * ) to char .
  • ptr2 is a pointer ( * ) to int const . The ptr2 variable points to is constant and can not be changed. We can change ptr2 and point it somewhere else.
  • ptr3 is a constant pointer ( const * ) to an int . The ptr3 variable itself is constant and can be assigned only once. The variable that ptr points to isn’t constant and can be changed.
  • ptr4 is a constant pointer ( const * ) to a constant ( const int ). The ptr4 variable itself is constant and can’t be changed to point to a different variable. The variable that ptr4 points to is also constant and can’t be changed.

Check the animation below:

The code below goes through the examples and contains both correct and incorrect assignments.

Feel free to play with the code, comment, and uncomment lines and see what happens! Make sure to read the declarations from right to left to understand them.

Next: Assigning Function Pointers , Up: Function Pointers   [ Contents ][ Index ]

22.5.1 Declaring Function Pointers

The declaration of a function pointer variable (or structure field) looks almost like a function declaration, except it has an additional ‘ * ’ just before the variable name. Proper nesting requires a pair of parentheses around the two of them. For instance, int (*a) (); says, “Declare a as a pointer such that *a is an int -returning function.”

Contrast these three declarations:

The possible argument types of the function pointed to are the same as in a function declaration. You can write a prototype that specifies all the argument types:

or one that specifies some and leaves the rest unspecified:

or one that says there are no arguments:

You can also write a non-prototype declaration that says nothing about the argument types:

For example, here’s a declaration for a variable that should point to some arithmetic function that operates on two double s:

Structure fields, union alternatives, and array elements can be function pointers; so can parameter variables. The function pointer declaration construct can also be combined with other operators allowed in declarations. For instance,

declares foo as a pointer to a function that returns type int ** , and

declares foo as an array of 30 pointers to functions that return type int ** .

declares foo as a pointer to a pointer to a function that returns type int ** .

CHAPTER 1: What is a pointer?

CS115 Lab: C++ Pointers

Highlights of this lab:, online videos, lab exercise:, definition of a pointer., pointer operators., simple pointer use..

Click here to download a simple pointer program.

Using Pointers to Pass Parameters by Reference.

Now, when the function is executed, the values of a and b will be changed in the main program.

(Click to download swap.cpp )

Why do we have to put the * in front of x and y when we are doing assignment?

Note that our call from main will be:

It may seem like we have added a level of complexity to pass by reference, but trust me, this information will help you if you ever work with traditional C functions (found in CS330).

Next, we will look at how pointers are used with C++ structures.

Pointers and Structures

Dynamic data and pointers., pointers running wild.

Normal people deal with the core file more simply: rm core does the trick quite nicely. That can be a truly big file, so you don't want it hanging around taking up your disk space.

But what about the problem that caused the dump in the first place?! Well, if you're using pointers in your program, it's likely that one of them took on a bad value. Go back to your source code and look for statements that change pointer values. Remember that when you are in emacs , you can search for a particular string (such as the name of a pointer) by entering: C-s search_string

cppreference.com

Assignment operators.

Assignment operators modify the value of the object.

[ edit ] Definitions

Copy assignment replaces the contents of the object a with a copy of the contents of b ( b is not modified). For class types, this is performed in a special member function, described in copy assignment operator .

For non-class types, copy and move assignment are indistinguishable and are referred to as direct assignment .

Compound assignment replace the contents of the object a with the result of a binary operation between the previous value of a and the value of b .

[ edit ] Assignment operator syntax

The assignment expressions have the form

  • ↑ target-expr must have higher precedence than an assignment expression.
  • ↑ new-value cannot be a comma expression, because its precedence is lower.

[ edit ] Built-in simple assignment operator

For the built-in simple assignment, the object referred to by target-expr is modified by replacing its value with the result of new-value . target-expr must be a modifiable lvalue.

The result of a built-in simple assignment is an lvalue of the type of target-expr , referring to target-expr . If target-expr is a bit-field , the result is also a bit-field.

[ edit ] Assignment from an expression

If new-value is an expression, it is implicitly converted to the cv-unqualified type of target-expr . When target-expr is a bit-field that cannot represent the value of the expression, the resulting value of the bit-field is implementation-defined.

If target-expr and new-value identify overlapping objects, the behavior is undefined (unless the overlap is exact and the type is the same).

In overload resolution against user-defined operators , for every type T , the following function signatures participate in overload resolution:

For every enumeration or pointer to member type T , optionally volatile-qualified, the following function signature participates in overload resolution:

For every pair A1 and A2 , where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signature participates in overload resolution:

[ edit ] Built-in compound assignment operator

The behavior of every built-in compound-assignment expression target-expr   op   =   new-value is exactly the same as the behavior of the expression target-expr   =   target-expr   op   new-value , except that target-expr is evaluated only once.

The requirements on target-expr and new-value of built-in simple assignment operators also apply. Furthermore:

  • For + = and - = , the type of target-expr must be an arithmetic type or a pointer to a (possibly cv-qualified) completely-defined object type .
  • For all other compound assignment operators, the type of target-expr must be an arithmetic type.

In overload resolution against user-defined operators , for every pair A1 and A2 , where A1 is an arithmetic type (optionally volatile-qualified) and A2 is a promoted arithmetic type, the following function signatures participate in overload resolution:

For every pair I1 and I2 , where I1 is an integral type (optionally volatile-qualified) and I2 is a promoted integral type, the following function signatures participate in overload resolution:

For every optionally cv-qualified object type T , the following function signatures participate in overload resolution:

[ edit ] Example

Possible output:

[ edit ] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

[ edit ] See also

Operator precedence

Operator overloading

  • Recent changes
  • Offline version
  • What links here
  • Related changes
  • Upload file
  • Special pages
  • Printable version
  • Permanent link
  • Page information
  • In other languages
  • This page was last modified on 25 January 2024, at 22:41.
  • This page has been accessed 410,142 times.
  • Privacy policy
  • About cppreference.com
  • Disclaimers

Powered by MediaWiki

How to get the base type of opaque pointer?

I would like to know what is the base type of a pointer in a structure definition.

For example the following code:

It corresponds to the following IR:

I want to know how to determine at the IR level that the ptr of class B points to struct A? Is there an existing passes?

Can anyone help me?

The short answer is that such type information isn’t all that reliable at the level of LLVM IR, and it is generally better to organize any passes to not need to care about the details of a pointer other than that it is a pointer (and its address space, for those targets where address spaces are relevant, largely GPU targets).

Depending on your use case, a good enough answer may be to look for an alloca of that struct type, track down getelementptr references to the corresponding field, and see what the type of corresponding loads and stores are and guess that it’s a reasonable default. But in general, treating a ptr as void * (in C terms) with implicit bitcasts to the appropriate type of any load or store instruction using that pointer is generally the best default if you’re trying to turn opaque pointer IR back into typed pointer IR.

Thanks for the reply, I will try what you said!

Related Topics

Firefox is no longer supported on Windows 8.1 and below.

Please download Firefox ESR (Extended Support Release) to use Firefox.

Download Firefox ESR 64-bit

Download Firefox ESR 32-bit

Firefox is no longer supported on macOS 10.14 and below.

Mozilla Foundation Security Advisory 2024-18

Security vulnerabilities fixed in firefox 125.

  • Firefox 125

# CVE-2024-3852: GetBoundName in the JIT returned the wrong object

Description.

GetBoundName could return the wrong version of an object when JIT optimizations were applied.

  • Bug 1883542

# CVE-2024-3853: Use-after-free if garbage collection runs during realm initialization

A use-after-free could result if a JavaScript realm was in the process of being initialized when a garbage collection started.

  • Bug 1884427

# CVE-2024-3854: Out-of-bounds-read after mis-optimized switch statement

In some code patterns the JIT incorrectly optimized switch statements and generated code with out-of-bounds-reads.

  • Bug 1884552

# CVE-2024-3855: Incorrect JIT optimization of MSubstr leads to out-of-bounds reads

In certain cases the JIT incorrectly optimized MSubstr operations, which led to out-of-bounds reads.

  • Bug 1885828

# CVE-2024-3856: Use-after-free in WASM garbage collection

A use-after-free could occur during WASM execution if garbage collection ran during the creation of an array.

  • Bug 1885829

# CVE-2024-3857: Incorrect JITting of arguments led to use-after-free during garbage collection

The JIT created incorrect code for arguments in certain cases. This led to potential use-after-free crashes during garbage collection.

  • Bug 1886683

# CVE-2024-3858: Corrupt pointer dereference in js::CheckTracedThing<js::Shape>

It was possible to mutate a JavaScript object so that the JIT could crash while tracing it.

  • Bug 1888892

# CVE-2024-3859: Integer-overflow led to out-of-bounds-read in the OpenType sanitizer

On 32-bit versions there were integer-overflows that led to an out-of-bounds-read that potentially could be triggered by a malformed OpenType font.

  • Bug 1874489

# CVE-2024-3860: Crash when tracing empty shape lists

An out-of-memory condition during object initialization could result in an empty shape list. If the JIT subsequently traced the object it would crash.

  • Bug 1881417

# CVE-2024-3861: Potential use-after-free due to AlignedBuffer self-move

If an AlignedBuffer were assigned to itself, the subsequent self-move could result in an incorrect reference count and later use-after-free.

  • Bug 1883158

# CVE-2024-3862: Potential use of uninitialized memory in MarkStack assignment operator on self-assignment

The MarkStack assignment operator, part of the JavaScript engine, could access uninitialized memory if it were used in a self-assignment.

  • Bug 1884457

# CVE-2024-3863: Download Protections were bypassed by .xrm-ms files on Windows

The executable file warning was not presented when downloading .xrm-ms files. Note: This issue only affected Windows operating systems. Other operating systems are unaffected.

  • Bug 1885855

# CVE-2024-3302: Denial of Service using HTTP/2 CONTINUATION frames

There was no limit to the number of HTTP/2 CONTINUATION frames that would be processed. A server could abuse this to create an Out of Memory condition in the browser.

  • Bug 1881183
  • VU#421644 - HTTP/2 CONTINUATION frames can be utilized for DoS attacks

# CVE-2024-3864: Memory safety bug fixed in Firefox 125, Firefox ESR 115.10, and Thunderbird 115.10

Memory safety bug present in Firefox 124, Firefox ESR 115.9, and Thunderbird 115.9. This bug showed evidence of memory corruption and we presume that with enough effort this could have been exploited to run arbitrary code.

  • Memory safety bug fixed in Firefox 125, Firefox ESR 115.10, and Thunderbird 115.10

# CVE-2024-3865: Memory safety bugs fixed in Firefox 125

Memory safety bugs present in Firefox 124. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.

  • Memory safety bugs fixed in Firefox 125

IMAGES

  1. PPT

    definition of pointer assignment

  2. Pointer Assignment Detailed Explanation Made Easy Lec-61 Learning Monkey

    definition of pointer assignment

  3. Pointer Assignment Detailed Explanation Made Easy Lec-61 Learning Monkey

    definition of pointer assignment

  4. Pointer Assignment Detailed Explanation Made Easy Lec-61 Learning Monkey

    definition of pointer assignment

  5. Pointer Assignment Detailed Explanation Made Easy Lec-61 Learning Monkey

    definition of pointer assignment

  6. PPT

    definition of pointer assignment

VIDEO

  1. C Language || Pointers in C || Part-4: Pointer Assignment in C || Telugu Scit Tutorial

  2. pointerAssignment

  3. What are Pointers? How to Use Them? and How they can Improve your C++ Programming Skills

  4. Pointers in c language

  5. Pointers

  6. What are Pointers? How to Use Them? and How they can Improve your C++ Programming Skills

COMMENTS

  1. C Pointers

    Syntax of C Pointers. The syntax of pointers is similar to the variable declaration in C, but we use the ( * ) dereferencing operator in the pointer declaration.. datatype * ptr;. where. ptr is the name of the pointer.; datatype is the type of data it is pointing to.; The above syntax is used to define a pointer to a variable.

  2. Pointer Basics

    Pointer assignment between two pointers makes them point to the same pointee. So the assignment y = x; makes y point to the same pointee as x. Pointer assignment does not touch the pointees. It just changes one pointer to have the same reference as another pointer. After pointer assignment, the two pointers are said to be "sharing" the pointee.

  3. C++ pointer assignment

    Now we have two variables x and y: int *p = &x; int *q = &y; There are declared another two variables, pointer p which points to variable x and contains its address and pointer q which points to variable y and contains its address: x = 35; y = 46; Here you assign values to the variables, this is clear: p = q;

  4. 12.7

    Simplifying a bit, when the code generated for this definition is executed, a piece of memory from RAM will be assigned to this object. ... Pointers and assignment. We can use assignment with pointers in two different ways: To change what the pointer is pointing at (by assigning the pointer a new address) ...

  5. Pointers

    This is a standard assignment operation, as already done many times in earlier chapters. The main difference between the second and third statements is the appearance of the address-of operator (&). The variable that stores the address of another variable (like foo in the previous example) is what in C++ is called a pointer. Pointers are a very ...

  6. 4.3. Pointer Operators

    Pointer assignment results in two pointers pointing to the same data. The assignment operation does not copy the data. sizeof forms an expression that is the size, measured in bytes, of the argument. When applied to a pointer variable, it returns the size of the pointer, not the size of the data to which it points.

  7. How C-Pointers Works: A Step-by-Step Beginner's Tutorial

    To declare and initialize a pointer to a pointer, you need to add an extra asterisk (*) compared to a regular pointer. Let's go through an example: int x = 10; int *ptr1 = &x; // Pointer to an integer int **ptr2 = &ptr1; // Pointer to a pointer to an integer. In this example, ptr2 is a pointer to a pointer.

  8. C Pointers (With Examples)

    Explanation of the program. int* pc, c; Here, a pointer pc and a normal variable c, both of type int, is created. Since pc and c are not initialized at initially, pointer pc points to either no address or a random address. And, variable c has an address but contains random garbage value.; c = 22; This assigns 22 to the variable c.That is, 22 is stored in the memory location of variable c.

  9. 12.9

    A const pointer is a pointer whose address can not be changed after initialization. ... a const pointer must be initialized upon definition, and this value can't be changed via assignment: int main() { int x{ 5 }; int y{ 6 }; int* const ptr { &x }; // okay: the const pointer is initialized to the address of x ptr = &y; // error: once ...

  10. CS31: Intro to C Structs and Pointers

    C Stucts and Pointers. This is the second part of a two part introduction to the C programming language. It is written specifically for CS31 students. The first part covers C programs, compiling and running, variables, types, operators, loops, functions, arrays, parameter passing (basic types and arrays), standard I/O (printf, scanf), and file ...

  11. An In-Depth Understanding of Memory and Pointers in C

    Pointers hold a reference to another variable or the address of another variable. The address of a variable is the point in memory where the operating system decided to place it or the address of the box where we put that variable. To create a pointer, we can use type* ptr. In other words, add an asterisk * to the regular variable declaration.

  12. Declaring Function Pointers (GNU C Language Manual)

    The declaration of a function pointer variable (or structure field) looks almost like a function declaration, except it has an additional ' * ' just before the variable name. Proper nesting requires a pair of parentheses around the two of them. For instance, int (*a) (); says, "Declare a as a pointer such that *a is an int -returning ...

  13. C Pointers Tutorial: Chapter 1

    The lvalue is the value permitted on the left side of the assignment operator '=' (i.e. the address where the result of evaluation of the right side ends up). The rvalue is that which is on the right side of the assignment statment, the '2' above. Note that rvalues cannot be used on the left side of the assignment statement.

  14. CS115 C++ Pointers Lab

    Definition of a Pointer. Pointers are a type of variable that allow you to specify the address of a variable. They provide a convenient means of passing arguments to functions and for referring to more complex datatypes such as structures. They are also essential if you want to use dynamic data in the free store area. (That was a free look ...

  15. c

    My intent in this answer is supplemental to the most basic of concepts of a null pointer. This simplest definition, as listed in many places is whenever a base value pointing to an address gets assigned a '0' or NULL value because the zero page, 0th memory location is part of the operating systems address space and operating system doesn't allow access to its address space by the user's program.

  16. Assignment operators

    Assignment performs implicit conversion from the value of rhs to the type of lhs and then replaces the value in the object designated by lhs with the converted value of rhs . Assignment also returns the same value as what was stored in lhs (so that expressions such as a = b = c are possible). The value category of the assignment operator is non ...

  17. Classes with Pointer Data Members

    Overview. Every class that has a pointer data member should include the following member functions: . a destructor, a copy constructor, operator= (assignment) The IntList class, defined in the "Introduction to C++ Classes" notes, includes a pointer to a dynamically allocated array. Here is the declaration of the IntList class again, augmented to include declarations of the class's destructor ...

  18. std::shared_ptr

    std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer. Several shared_ptr objects may own the same object. The object is destroyed and its memory deallocated when either of the following happens: the last remaining shared_ptr owning the object is destroyed; ; the last remaining shared_ptr owning the object is assigned another pointer via operator= or ...

  19. Assignment operators

    for assignments to class type objects, the right operand could be an initializer list only when the assignment is defined by a user-defined assignment operator. removed user-defined assignment constraint. CWG 1538. C++11. E1 ={E2} was equivalent to E1 = T(E2) ( T is the type of E1 ), this introduced a C-style cast. it is equivalent to E1 = T{E2}

  20. c++

    In C++, in most cases, whenever you use an array, it is implicitly converted to a pointer to its initial element. So here, int* a = x is the same as int* a = &x[0];. (There are several cases where the array-to-pointer decay does not occur, most notably when the array is the operand of the & or sizeof operators; they allow you to get the address ...

  21. How to get the base type of opaque pointer?

    I would like to know what is the base type of a pointer in a structure definition. For example the following code: struct A { int a; char b; long c; }; class B{ public: A *a; }; int main(){ A a = {1,'a',1000}; B b; b.a = &a; } It corresponds to the following IR: %struct.A = type { i32, i8, i64 } %class.B = type { ptr } @__const.main.a = private unnamed_addr constant %struct.A { i32 1, i8 97 ...

  22. Security Vulnerabilities fixed in Firefox 125

    # CVE-2024-3858: Corrupt pointer dereference in js::CheckTracedThing<js::Shape> Reporter Lukas Bernhard Impact high Description. It was possible to mutate a JavaScript object so that the JIT could crash while tracing it. References. Bug 1888892 # CVE-2024-3859: Integer-overflow led to out-of-bounds-read in the OpenType sanitizer Reporter Ronald ...

  23. c++

    4. Correct me if I'm wrong: I understand that when having a class with members that are pointers, a copy of a class object will result in that the pointers representing the same memory address. This can result in changes done to one class object to affect all copies of this object. A solution to this can be to overload the = operator.