Advanced Concepts of C/C++ Paraqum Technologies (pvt) Ltd. Pointers A pointer is a variable that stores the memory address of an object. Pointers are used extensively in both C and C++ for three main purposes: ● to allocate new objects ● to pass parameters to functions ● to iterate over elements in arrays or other data structures Size of a Pointer The size of a pointer is a fixed value solely depends on the memory address space of the system ( 32 bit 64 bit etc.) Pointer Definition Address of a Variable Ampersand (&) operator denotes an address in memory Address of var: 0x7ffe03e1f344 Definition of a Pointer Asterisk (*) operator denotes a pointer A pointer has no type since it’s just a memory address, however for the sake of avoiding confusion of the programmer and to be complied with C++ standards, pointers needs to have a type. Assigning a Pointer A memory address can be assigned to a pointer Pointer Arithmetic Since they are memory addresses, we often perform increment (++) , decrement(--), addition and subtraction operations on pointers. When we increment or decrement the pointer, then the pointer is increased or decreased by a block of memory . Output Pointer of a Pointer A pointer to a pointer is a form of multiple indirection or a chain of pointers. Normally, a pointer contains the address of a variable. When we define a pointer to a pointer, the first pointer contains the address of the second pointer Declaring Double Pointers int **ptr; Data Structures Structure is user defined data type which allows you to combine data items of different kinds. Accessing Structure members operator Use a dot(.) between the variable name and the member element as the access operator . Pointers to structures operator Use “->” between the variable name and the member element as the access operator . Memory Align/Cache Align Data Structures ● ● ● Memory/Cache data are often fetched as large blocks ( 32bit, 64bit, 128bit etc) by the CPU We can reduce memory latency while accessing data inside an structure If we arrange our data as blocks ( aligning ) Memory/Cache aligning data structures may Improve the performance of high speed Computations significantly Green: int Pink: char Purple: short Union A union is a user-defined data type having members of different data types. But unlike in ,structures all the members share the same memory location. We can access only one member of union at a time. Dynamic Memory Allocation C/C++ allows us to allocate the memory of a variable or an array in run time. This memory allocation in the Heap is known as dynamic memory allocation. Memory Allocation ● ● ● ● malloc() : allocate a single block of memory calloc() : allocate a set of blocks of memory realloc : resize an allocated block of memory new - in C++ Memory Release ● ● free() delete - in C++ Static Variables ● ● Space for a static variable is allocated for the lifetime of the program. Even if the function is called multiple times, space for the static variable is allocated only once and the value of variable in the previous call gets carried through the next function call. Extern Storage class ● ● ● Used to give a reference of a global variable that is visible to ALL the program files. Extends the visibility of function or variable. The extern modifier is most commonly used when there are two or more files sharing the same global variables or functions. Inline Functions When the program executes a function call instruction, 1. CPU stores the memory address of the instruction following the function call 2. CPU copies the arguments of the function on the stack 3. Transfers control to the specified function 4. CPU executes the function code 5. Stores the function return value in a predefined memory location/register and returns control to the calling function This process could be an overhead if function is small and function calling process may take more time than executing actual function ! Solution - Substitute the function call with the contents of the function where function is called = Branch Prediction ● ● ● Hints the compiler which lines of code would be most probably be executed Compiler can optimize its execution ( by code scheduling and prefetching most likely data to be executed) and that would result in faster code execution. Macros from linux kernel code “likely()” and “unlikely()” will help us in branch prediction. Multithreading A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread defines a separate path of execution C does not contain built-in support for multithreading Therefore it uses library support from the OS. Thread Safety If multiple threads access and modify same data simultaneously, unpredictable results may occur To prevent this from happening, 1. Lock the data while being accessed by one thread so other threads cannot modify unless released by the occupied thread I.e - mutex 2. Use specific data types that cannot be modified by multiples threads simultaneously I.e - Atomic Data types ( reading and writing are guaranteed to happen in a single instruction ) Performance Tuning Tools - perf Performance tuning tools such as perf, vtune are used to determine performance bottlenecks of the programs. These tools can determine events such as, ● ● ● ● ● ● ● ● ● ● ● ● ● ● ● cpu-cycles OR cycles instructions cache-references cache-misses branch-instructions OR branches branch-misses bus-cycles cpu-clock task-clock page-faults OR faults context-switches OR cs cpu-migrations OR migrations minor-faults major-faults alignment-faults