ProgrammingC Developer

Describe the mechanism of the dereference operator (*) and the address-of operator (&) in the C language. What are the basic principles of their usage, what are typical pitfalls, and how does dereferencing different types of pointers differ?

Pass interviews with Hintsage AI assistant

Answer.

In the C language, pointers and dereferencing operations are fundamental to manual memory management and low-level programming. The address-of operator (&) returns the address of a variable in memory, creating a pointer. The dereference operator (*) allows access to the value pointed to by a pointer. These tools enable the implementation of complex data structures, memory management, passing large objects by address, and direct interaction with hardware.

History of the question
The emergence of pointers and these operators was a necessary step to provide programmers with the ability to work directly with memory, ensuring efficiency and flexibility in writing system-level applications and drivers.

Problem
Constant manual memory management and explicit dereferencing can easily lead to errors: for example, accessing freed memory, incorrect types, loss of access to allocated areas, and uncontrolled memory leaks.

Solution
Proper and careful use of the operators * and &, strict adherence to types, understanding the differences between pointers of different types, and following rules of scope and lifetime of data.

Example code:

#include <stdio.h> void increment(int *p) { (*p)++; } int main() { int x = 10; int *ptr = &x; increment(ptr); // x will increase to 11 printf("%d\n", x); // output: 11 return 0; }

Key features:

  • Ability for direct memory access: effectively use memory by modifying data at a given address.
  • Typing: pointers must match the type of the variable; dereferencing different types may lead to undesirable consequences.
  • Interacting with functions: allows implementing mutable parameters and returning complex structures.

Tricky questions.

Can dereferencing an arbitrary pointer cause a segmentation fault?

Yes, if dereferencing an incorrect or uninitialized pointer, the program will terminate with an exception. For example:

int *a = NULL; printf("%d", *a); // Segmentation fault

What happens if you take the address of a temporary value (e.g., the result of an expression)?

In C, you cannot take the address of a temporary result of an arithmetic expression directly, only the address of a variable:

int x = 5; int *p = &(x + 1); // Compilation error

Can you dereference void?*

No, you cannot. The void* pointer is universal, but it must be cast to a specific type before dereferencing:

void* p = ...; int val = *(int*)p; // First cast, then dereference

Common errors and anti-patterns

  • Dereferencing uninitialized or NULL pointers.
  • Mismatched pointer and variable types during dereferencing.
  • Loss of control over memory area (leak).

Real-life example

Negative case

A junior developer freed memory using free(ptr), but then mistakenly tried to access *ptr, causing the application to crash.

Pros:

  • Quickly detected memory errors speed up bug fixing.

Cons:

  • Crash on the user side, difficult to diagnose.
  • Can lead to data corruption.

Positive case

An experienced developer always nullifies the pointer after freeing memory: free(ptr); ptr = NULL;. Before dereferencing, they always check for NULL.

Pros:

  • Increased code reliability.
  • Easy to catch deinitialized pointers.

Cons:

  • Requires strict discipline, increases the amount of check code.