Pointers, Structs, and Memory Allocation

Choose a study mode

Play Quiz
Study Flashcards
Spaced Repetition
Chat to Lesson

Podcast

Listen to an AI-generated conversation about this lesson
Download our mobile app to listen on the go
Get App

Questions and Answers

Consider a scenario where an engineer is tasked with optimizing legacy code dependent on function pointers for polymorphism. What subtle risk is most pertinent when transitioning to a virtual function-based approach in C++?

  • Inability to perform compile-time optimizations such as inlining, which were previously possible with function pointers.
  • Potential for binary incompatibility if the size or layout of objects changes, affecting existing serialized data. (correct)
  • Increased compile-time dependencies due to the introduction of vtables.
  • Reliance on dynamic linking introduces overhead in dispatching calls to polymorphic functions, undermining performance gains.

In the context of C structs, what is the most critical implication of contiguous memory storage on optimizing data structure access?

  • It mandates manual memory alignment to avoid segmentation faults on architectures with strict alignment requirements.
  • It simplifies garbage collection algorithms by guaranteeing object lifetimes based on struct allocation scope.
  • It necessitates the use of explicit padding to ensure cross-platform compatibility of struct layouts.
  • It allows for more efficient use of cache lines when traversing sequential struct members, reducing memory access latency. (correct)

When designing a data structure using dynamic memory allocation, which factor poses the most significant challenge to long-term system stability?

  • The risk of memory fragmentation leading to allocation failures, especially in long-running processes. (correct)
  • The potential for stack overflow errors when deallocating large memory blocks.
  • The impact on virtual memory performance due to increased page swapping.
  • The overhead of maintaining metadata for allocated memory blocks, increasing memory footprint.

Given an enumerated Weekdays type in C++ starting with MONDAY = 20, and subsequent days incrementing by one, what would be the most efficient method, without introducing branching, to determine if a given integer x falls within the valid range of the Weekdays enumeration?

<p>Checking if <code>x</code> is both greater than or equal to <code>MONDAY</code> and less than or equal to the last weekday. (B)</p>
Signup and view all the answers

In the context of using C unions to optimize memory usage in embedded systems, what is the most critical consideration when sharing memory locations between different data types?

<p>Managing data alignment to prevent bus errors when accessing union members on architectures with strict alignment requirements. (A)</p>
Signup and view all the answers

In Bash scripting, what security vulnerability is mitigated by using parameterized queries or prepared statements (if available) instead of directly embedding user input into commands, and how does it prevent the issue?

<p>Command Injection: By sanitizing user input to prevent the execution of arbitrary commands. (B)</p>
Signup and view all the answers

Which of the following strategies is most effective in preventing race conditions when multiple threads access and modify shared data structures?

<p>Employing mutexes to guard critical sections of code that access the shared data, ensuring exclusive access by one thread at a time. (B)</p>
Signup and view all the answers

When implementing a custom memory allocator in C++, which strategy offers the most effective balance between minimizing fragmentation and reducing allocation overhead, especially in scenarios with variable-sized allocations and frequent deallocations?

<p>Implementing a buddy system allocator with binary splitting and merging of blocks. (A)</p>
Signup and view all the answers

What is the most significant drawback of relying solely on static libraries for linking in a large-scale software project with numerous dependencies?

<p>Duplication of library code in each executable, leading to increased disk space usage and memory footprint. (D)</p>
Signup and view all the answers

When transitioning a legacy C codebase to use shared libraries, what critical step must be taken to ensure that the application correctly resolves symbols at runtime, especially when dealing with complex dependency chains?

<p>Ensure that all shared libraries are linked with the <code>-fPIC</code> flag to generate position-independent code. (C)</p>
Signup and view all the answers

In the context of exception handling, what is the most crucial difference between a fault and a trap, and how does this difference influence the system's response?

<p>Faults are synchronous errors that can potentially be corrected and the instruction re-executed, while traps are asynchronous software-initiated interrupts used for system calls. (D)</p>
Signup and view all the answers

When designing a real-time operating system (RTOS), what is the most critical factor in minimizing interrupt latency, and how does it directly impact the predictability of task scheduling?

<p>Minimizing the size of interrupt handlers to reduce the time spent in interrupt context. (B)</p>
Signup and view all the answers

In a multi-process environment, what is the most effective strategy for minimizing the overhead associated with inter-process communication (IPC) when transmitting large volumes of data?

<p>Employing shared memory to allow processes to directly access the same memory region. (D)</p>
Signup and view all the answers

Consider a multi-threaded application where threads frequently contend for a mutex lock. Which strategy is most effective in reducing lock contention and improving overall throughput?

<p>Breaking the critical section into smaller, independent sections with separate mutexes. (C)</p>
Signup and view all the answers

What is the most significant risk associated with using semaphores for resource synchronization, and how can this risk be mitigated?

<p>Deadlock, which can be mitigated by establishing a strict ordering for acquiring semaphores. (B)</p>
Signup and view all the answers

In the context of signal handling, what is the most critical reason for using asynchronous-signal-safe functions within signal handlers, and what type of unpredictable behavior can result from using non-safe functions?

<p>To prevent reentrancy issues, as non-safe functions may call themselves indirectly through signal handling, corrupting internal state. (D)</p>
Signup and view all the answers

When designing a client-server application, what is the most effective strategy for mitigating the risk of denial-of-service (DoS) attacks that exploit the TCP handshake process?

<p>Using SYN cookies to validate incoming connection requests without allocating resources until the handshake is complete. (D)</p>
Signup and view all the answers

In network programming, what is the most fundamental difference between TCP and UDP, and how does this difference affect the suitability of each protocol for different types of applications?

<p>TCP is connection-oriented and provides reliable, ordered delivery, while UDP is connectionless and provides unreliable, unordered delivery. (C)</p>
Signup and view all the answers

When implementing a multi-process application on a Unix-like system, what is the most effective technique for ensuring that child processes inherit a consistent and synchronized state from the parent process, particularly when dealing with complex data structures and file descriptors?

<p>Using a combination of <code>fork()</code> and copy-on-write semantics to minimize memory overhead while ensuring data consistency. (A)</p>
Signup and view all the answers

In the context of CPU scheduling algorithms, what is the most significant factor that determines the performance of the Shortest Job First (SJF) algorithm, and what practical limitation often prevents its optimal implementation?

<p>The accuracy of predicting future CPU burst times, as SJF requires knowing the duration of each job in advance. (C)</p>
Signup and view all the answers

Flashcards

What is Polymorphism?

Ability to change behavior at run-time.

What is a struct?

A user-defined data type that groups different types into a single type.

How are struct values stored?

Members are stored sequentially in memory, one after another.

Dynamic Memory Allocation?

Useful for dynamic structures like linked lists and trees.

Signup and view all the flashcards

Passing a pointer?

More efficient because only the memory address is passed.

Signup and view all the flashcards

What are Enums?

A user-defined data type for representing a group of global constants.

Signup and view all the flashcards

Issue with #define?

Doesn't establish type checking or obey scope rules like enums do.

Signup and view all the flashcards

What is a union?

A user defined data type where members overlap in storage, allowing only one to hold a value at a time.

Signup and view all the flashcards

What is BASH?

Known as Bourne Again Shell, it is a command interpreter and a high-level programming language.

Signup and view all the flashcards

What does Shebang do?

Tells the operating system which shell to execute the file.

Signup and view all the flashcards

What is redirection?

Change where standard input of a command comes from or where standard output goes.

Signup and view all the flashcards

What is a file descriptor?

The place a program sends its output to and gets its input from; includes standard input, output, and error.

Signup and view all the flashcards

Structure of Node?

Doubly linked list using a struct allows traversal in both directions.

Signup and view all the flashcards

Purpose of #include?

Load the content of header files, so that they can be used in the program.

Signup and view all the flashcards

What is linking?

The process of collecting and combining various pieces of code and data into a single file.

Signup and view all the flashcards

What is symbol resolution?

Associate each symbol reference with exactly one symbol definition.

Signup and view all the flashcards

Dynamic linking?

During runtime or load time, can be loaded at an arbitrary memory address and linked with a program in memory.

Signup and view all the flashcards

Simplest control flow?

Startup to Shutdown, a CPU reads and executes instructions one at a time.

Signup and view all the flashcards

The four exception classes?

Interrupts, Traps, Faults, Aborts

Signup and view all the flashcards

What is a signal?

A small message notifying a process that an event has occurred.

Signup and view all the flashcards

Study Notes

Lecture 11

  • Pointers to functions implement polymorphism
  • This changes the behavior, it can change at run-time which differs from static function calls.
  • Without encapsulating the pointer name in parentheses for a function pointer, the compiler will mistake it.
  • A struct is a user defined data type that groups different types of items into a single type
  • The items inside a struct are known as members
  • Values in structs are stored contiguously in memory
  • Members of a structure can be directly accessed using the "." operator
  • Memory can be allocated dynamically when the size is unknown at compile time
  • This is useful for building data structures like linked lists, trees, and graphs
  • When accessing members of a structure using pointers, the arrow operator (->) must be used
  • It's more efficient to pass a pointer to a function versus the entire structure because only the memory address is passed
  • Explicit memory allocation is faster than implicit memory allocation
  • It uses less memory but throws more errors

Lecture 12

  • Enums are a user defined data type that represent a group of global constants
  • An example of an Enum is Days of the Week
  • Using an Enum is better because it does not establish any type checking, and does not obey scope rules
  • When using #define, related variables cannot be grouped
  • The default value assigned to each member of the enum is 0
  • Each value increases by 1
  • For an enum Weekdays { MONDAY = 20, TUESDAY = 30, WEDNESDAY = 40, THURSDAY = 50, FRIDAY = 60 };
  • TUESDAY = 30
  • THURSDAY = 50
  • A union is a user defined datatype consisting of a sequence of members whose storage overlaps
  • Data types can be stored, but since it is all-shared memory space, only one member can hold a value at any given time.
  • Only 1 member can hold a value at one time
  • Size of a union is based on the size of its largest member
  • Unions save space and memory, useful for plugins, slicing network packets

Lecture 13

  • Members of a union can be accessed using the "." operator
  • BASH, also known as the Bourne Again Shell, it's a command interpreter and a high-level programming language
  • Scripting requires the shebang sequence of characters (#!) / (#!/bin/bash) on the first line
  • This tells the operating system which shell should execute the file and follows the pathname
  • When a script is created, its permissions must be updated so it can be read and executed
  • Examples of permission combinations:
  • 777 → Read, write, and execute for the owner, group, and others.
  • 666 → Read and write for everyone
  • 444 → Read-only for everyone
  • BASH scripts can be expected to be analyzed
  • Redirection encompasses the ways to alter where the standard input of a command comes from and where the standard output goes to
  • Redirection uses the symbols < and >
  • A file descriptor is a place where a program sends its output to and gets its input from
  • There are 3 file descriptors: Standard input, Standard output, standard error.
  • /etc/passwd is important because you can read and identify users in this file
  • The actual passwords are NOT stored in /etc/passwd
  • The first four fields of a /etc/passwd entry is for represtation

Lecture 14

  • The steps needed to add a node to the front/tail of a list in a doubly linked list
  • Doubly linked list using a struct
struct Node{
   int data;
   struct Node* next;
   struct Node* prev;
};
struct Node* createNode (int data) {
   struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
   newNode->data = data;
   newNode->next = NULL;
   newNode->prev = NULL;
   return newNode;
}

Lecture 14_3

  • Header files include the #include <header.h> directive
  • The C preprocessing directive #include is a request to the compiler
  • Its purpose is to load the contents of a specific header file so that they can be used in the program
  • Double inclusion is including the header file in multiple files
  • The solution for double inclusion is to include the same header file twice or a Header Guard
  • Header guards work by checking if it's been defined before.
  • If it's the first time it won't be defined so then it will be ignored
  • Linking is the process of collecting and combining various pieces of code and data into a single file that can be copied into memory and executed
  • It can be done at compile time, load time, and run time
  • Linking multiple files together leads to better optimization

Lecture 15

  • Symbol resolution associates each symbol reference with exactly one symbol definition
  • A symbol table is an array of structs
  • Each entry contains the name, size, and location of the symbol.
  • Relocation
  • Three different types of object files:
  • Relocatable object (.o file)
  • Executable object file (a.out file)
  • Shared object file (.so file)
  • Global, external, and local symbols
  • When dealing with duplicate symbols:
  • Multiple strong symbols are not allowed
  • Each item can only be defined once
  • Otherwise, a Linker Error is created
  • Given a strong symbol and multiple weak symbols, choose the strong symbol.
  • If there are multiple weak symbols, pick an arbitrary one.

Lecture 16_2

  • Putting all standard C functions into a single relocatable object module is bad because it is a huge waste of space
  • A change would require recompilation of the entire source code.
  • Static libraries are stored on disk in Archive files.
  • The disadvantages of static libraries:
  • Duplication in stored exe
  • Duplication in running exe
  • Minor bug fixes of system libraries require each application to explicitly relink.
  • Shared Libraries, are the modern solution
  • Dynamic linking can be loaded at runtime or load time
  • Loading can be performed at an arbitrary memory address and linked with a program in memory.
  • Shared libraries are "shared" in two ways:
  • One .so file
  • A single copy of the text section of a shared library in memory

Lecture 17

  • The simplest form of control flow is Startup to Shutdown
  • A CPU reads and executes a sequence of instructions, one at a time (CPU Control Flow)
  • Events that cause abrupt changes in control on the system may include:
  • Instruction divides by zero
  • Data from disk or network adapter
  • Control
  • Hardware timer goes off
  • These abrupt changes are referred to as Exceptional Control Flow (ECF)
  • The three levels of the computer system where exceptional control flow can occur:
  • The Hardware
  • OS
  • Application level
  • An exception is the transfer of control to the OS kernel in response to some event (like a change in the processor state)
  • An "event" is a significant change that occurs
  • Types of exceptions: Interrupts, traps, faults, aborts
  • A process is an instance of a program in execution
  • In a logical control flow, processes take turns using the processor
  • Each process executes a portion of its flow and then is preempted while other processes take their turns
  • Preempted means that it's temporarily suspended
  • A logical flow whose execution overlaps in time with another flow is called a concurrent flow

Lecture 18

  • Init is is the first process in the system
  • The kernel assigns a unique ID number to every process
  • This ID is called a PID (Process ID)
  • Parent-child relationship is formed between processes
  • States a process may be in:
  • Ready/Runnable
  • Running
  • Zombie
  • Stopped
  • Terminated
  • Sleeping
  • The process table contains all the information of the processes

Lecture 19

  • A race condition is when threads can access shared data and try to change it at the same time
  • A mutex lock, also known as a mutual exclusion, is an operation used to prevent simultaneous possession of the shared resources.
  • Critical section is a portion of the code only one thread should execute at a time
  • Semaphores are used to coordinate access to resources
  • Binary and Counting are the two types of semaphores
  • The functions that lock/unlock a semaphore are Sem_post(), sem_wait()

Lecture 20

  • A signal is a small message that notifies a process of an event
  • A signal may be sent for sending or receiving purposes
  • When receiving a process, the process can do one of three things
  • Ignore
  • Catch
  • Terminate
  • A pending signal has been sent but not yet received
  • A process can selectively block the receipt of certain signals
  • Since there can be at most one pending signal of a particular type, the rest of the signals that may be of the same type, gets discarded
  • Each signal type has a predefined default action:
  • The Process terminates
  • The Process terminates and dumps core.
  • The process stops (suspends) until restarted by a SIGCONT signal.
  • The process ignores the signal
  • Steps needed for a transaction between a client and a server:
  • The client initiates a request to the server
  • The server is like OK what is this what are you looking for then stamps it for approval
  • The server sends a response to the client and waits
  • The client receives the response, then processes it
  • A network is a hierarchical system organized by geographical proximity
  • SAN, LAN, WAN, are three proximities
  • IP addresses are stored in memory for a network
  • Referred to as Dotted Decimal notation
  • A socket is an endpoint of a connection
  • A socket pair is indicated as (IP_adress:port)
  • An ephemeral port assigned automatically by client kernel when a client makes a connection request
  • A well-known port is associated with some service provided by a server
  • Converting byte order between the network and the client is necessary
  • Be able to fill in aspects of the socket address or the socket pair:
  • AF_INET is needed
  • SOCK_STREAM
  • Client, server, and socket file descriptors
  • Functions implement so the server can communicate with a client

Lecture 21

  • The main objective of multiprogramming is to to have some process always running, maximizing CPU utilization
  • CPU sitting idle is a waste, no work is being accomplished
  • When one process waits, the OS gives the CPU to another process.
  • The CPU scheduler selects a process from the processes in memory that are ready to execute and allocates the CPU to that process.
  • The process control block shows all the information stored
  • A preemptive scheme is when the OS can interrupt a running process and switch to another process before the current one finishes
  • A nonpreemptive scheme is when scheduling takes place until the process is finished.
  • Able to create the gantt chart and calculate the average wait time using each process
  • Use different approaches like First come first serve, Shortest job first (preemptive and nonpreemptive), Round robin
  • Calculate exponential averaging

Studying That Suits You

Use AI to generate personalized quizzes and flashcards to suit your learning preferences.

Quiz Team

Related Documents

More Like This

C Programming Functions and Pointers
10 questions
C++ Functions and Pointers
10 questions
CSIT 231: Function Pointers and Structs
45 questions
Use Quizgecko on...
Browser
Browser