0% found this document useful (0 votes)
32 views

Unit 4 Part B Study Material

Uploaded by

AjithaTeja
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views

Unit 4 Part B Study Material

Uploaded by

AjithaTeja
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

PS & PwC Unit 4

Study Material: Problem Solving and Programming with C


UNIT -4
PART B
2 Marks Questions
1. Define a pointer. Illustrate How is a pointer variable different from an ordinary
Variable
Pointer: A pointer is a variable that stores the memory address of another variable. It
acts as a reference to the actual value stored at that address.
int x = 10;
int *ptr = &x; // ptr stores the address of x
Feature Ordinary Variable Pointer Variable
Storage Stores a Value directly Stores a memory address
Access Accessed directly by its Accessed indirectly using *
name operator.
2. Write a short note on L values and R values.
1. L-value: An L-value (locator value) refers to an object that occupies some
identifiable location in memory (i.e., it has an address). L-values can appear on the
left side of an assignment statement. Examples include variables, array elements,
and dereferenced pointers.
2. R-value: An R-value (read value) refers to a data value that is not associated with a
specific memory location. R-values can appear on the right side of an assignment
statement. Examples include literals (like 5, 3.14), the results of expressions.
Example:
int a=3;
int b=5;
int c=a+b;
a, b, c are L-values (They occupy identifiable memory Location)
3, 5, a+b are R-values (They are not stored any where in the memory)
3. How are generic pointers different from pointer variables?
Pointer variables (e.g., int*, char*) are type-specific pointers that hold the address of a
particular data type, providing type safety and allowing direct dereferencing without
casting. In contrast, generic pointers, represented by void*, can point to any data type
but do not have type safety, requiring explicit casting before dereferencing. This
makes pointer variables ideal for specific data manipulation, while generic pointers
offer flexibility for functions that handle multiple types.
4. Explain what a wild pointer is and how it can affect program execution
• A wild pointer is a pointer that points to an arbitrary memory location.
• It can occur when a pointer is declared but not initialized.
• Accessing a wild pointer can lead to unpredictable behavior, such as program
crashes or data corruption.
Example
int a=5;
int *p;
int b=*p++;
The location which is being referred to by p is unknown and hence we will not be able
to comprehend the adversities program may face by changing its data.
5. What is dynamic memory allocation, and how does it differ from static memory
allocation?
PS & PwC Unit 4

Dynamic memory allocation refers to the process of allocating memory at runtime,


rather than at compile time. This allows for flexible memory management, enabling
programs to adapt to varying data requirements.
Feature Static Memory Allocation Dynamic Memory Allocation
Timing Compile Time Runtime
Memory Stack Heap
Location
Size Fixed Size Flexible Size
Lifetime Until Program termination or Manually deallocated using free()
function exit
Flexibility Less Flexible More Flexibile
6. In C, what happens if one tries to access memory that has been dynamically allocated
but has already been freed?
If you try to access memory that has been dynamically allocated but has already been
freed using the free () function, the behaviour is undefined. This means that the
program may crash, produce incorrect results, or exhibit other unexpected behaviour.

Here's why:

• Memory is reclaimed: Once memory is freed, the operating system reclaims it


for other purposes.

• Pointer becomes a dangling pointer: The pointer that was previously pointing
to the freed memory now becomes a dangling pointer.

• Access to invalid memory: Accessing the memory through the dangling pointer
can lead to unpredictable results.
PS & PwC Unit 4

Study Material: Problem Solving and Programming with C


UNIT -4
PART A
5 Marks Questions

1. What is a pointer? Explain the declaration, initialization, and accessing of a pointer


variable.
Pointer: A pointer is a variable that stores the memory address of another variable. It
acts as a reference to the actual value stored at that address.
int x = 10;
int *ptr = &x; // ptr stores the address of x
Declaration of a Pointer Variable:
To declare a pointer, we use * (asterisk) operator:
The syntax for declaring a pointer is
data_type *pointer_name;
Example:
int *ptr; // Pointer to an integer
char *ch_ptr; // Pointer to a character
Pointer variables are type specific they can only hold the address of a variable
belonging to the same type i.e. a point declared using int * can only hold the address of
an integer variable. However, a pointer declared using void * can hold the address of
any type.
Initialization of a Pointer Variable:
A pointer can be initialized with the address of a variable using the & (address-of)
operator.
Example:
int x = 10;
int *ptr = &x; // ptr now stores the address of x
Uninitialized pointers are called as wild pointers as they point to arbitrary memory
locations. To avoid it is a best practice to set any uninitialized pointer to NULL.
Accessing the Value Pointed to by a Pointer:
To access the value stored at the memory location pointed to by a pointer, we use the *
operator, known as the dereference operator.
int y = *ptr; // y now stores the value of x, which is 10
Generic pointers can’t be dereferenced directly they are to be type casted first and then
dereferenced. Dereferencing wild pointers may result in undefined behaviour.
Accessing a NULL pointer results in termination of the program.
Example program:
#include <stdio.h>
int main() {
int num = 10; int *ptr = &num;
printf("Value of num: %d\n", num);
printf("Address of num: %p\n", &num);
printf("Value of ptr: %p\n", ptr);
printf("Value at the address pointed to by ptr: %d\n", *ptr);
return 0;
}

2. What is address arithmetic in C? Explain different arithmetic operations that can be


performed on pointers
PS & PwC Unit 4

Address Arithmetic in C
Address arithmetic in C refers to the operations that can be performed on pointer
variables to navigate through arrays or memory locations. Since pointers store memory
addresses, arithmetic operations allow you to calculate and manipulate these addresses
effectively. The arithmetic operations on pointers take into account the size of the data
type to which the pointer points.
Arithmetic Operations on Pointers
1. Pointer Increment (++):
• When you increment a pointer (e.g., ptr++), it moves to the next memory
location based on the size of the data type it points to. For example, if ptr is
an int*, incrementing it will move the pointer forward by sizeof(int) bytes
int arr[] = {10, 20, 30};
int* ptr = arr; // Points to arr[0]
ptr++; // Now points to arr[1]
2. Pointer Decrement (--):
• Similar to incrementing, decrementing a pointer (e.g., ptr--) moves it to the
previous memory location based on the size of the data type.
int* ptr = arr + 2; // Points to arr[2]
ptr--; // Now points to arr[1]
3. Pointer Addition:
• You can add an integer value to a pointer (e.g., ptr + n), which moves the
pointer forward by n elements of the type it points to.
int* ptr = arr; // Points to arr[0]
ptr = ptr + 2; // Now points to arr[2]
4. Pointer Subtraction:
• You can subtract an integer from a pointer (e.g., ptr - n), which moves the
pointer backward by n elements.
int* ptr = arr + 2; // Points to arr[2]
ptr = ptr - 1; // Now points to arr[1]
5. Pointer Difference:
• You can subtract one pointer from another if both pointers point to
elements of the same array. This operation returns the number of elements
between the two pointers.
int* ptr1 = arr; // Points to arr[0]
int* ptr2 = arr + 2; // Points to arr[2]
int diff = ptr2 - ptr1; // diff will be 2
6. Pointer Comparison
• In C, pointers can be compared using relational operators. This comparison
is useful for various purposes, such as checking if two pointers refer to the
same memory location or determining their relative positions in memory
(e.g., whether one pointer points to an address before or after another).
Example Program:
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // ptr points to the first element of the array
// Accessing elements using pointer arithmetic
printf("%d\n", *(ptr + 1)); // Prints 20
printf("%d\n", *(ptr + 2)); // Prints 30
// Comparing pointers
if (ptr < (ptr + 3)) {
printf("ptr is less than ptr + 3\n");}
PS & PwC Unit 4

3. Using pointers in functions, write a C program to perform arithmetic operations on


two integers.
1. Analysis
Problem Description:
The objective is to perform arithmetic operations (addition, subtraction, multiplication,
and division) on two integers. We’ll use pointers to pass the addresses of these integers
to functions, allowing the functions to perform the operations directly on the values
pointed to by the pointers.
Technique Chosen:
We'll use pointer-based functions to carry out the operations. By passing pointers to
the integers, we can access and manipulate the values directly within the functions.
This approach avoids copying values, as the operations are performed on the addresses
of the variables.
Operations:
• Addition: Sum of two integers.
• Subtraction: Difference between two integers.
• Multiplication: Product of two integers.
• Division: Quotient when one integer is divided by another, provided the divisor
is non-zero.
We will define a function for each operation
Functionality of Each Arithmetic Function: Each function takes pointers to the two
integers (a and b) and a result pointer. The operations are performed directly on the
dereferenced values, and the result is stored in the variable pointed to by result.
Division Function: Handles the case where b is 0 to avoid division by zero, printing an
error message if this condition is met.
main Function: Calls each arithmetic function, passing pointers to a, b, and the
respective result variables. The results are then printed to the console.
2. Algorithm
Algorithm for main Function
1. Start.
2. Declare two integer variables a and b, and four more integer variables to store
results: sum, difference, product, and quotient.
3. Input values for a and b from the user.
4. Call the add, subtract, multiply, and divide functions, passing pointers to a, b,
and the respective result variables.
5. Display the results of each operation.
6. Stop.
Algorithm for Arithmetic Operation Functions
Each function receives pointers to a, b, and a result variable where the answer will be
stored.
1. Function for Addition
o Start.
o Dereference the pointers to calculate *result = *a + *b.
o Return.
2. Function for Subtraction
o Start.
o Dereference the pointers to calculate *result = *a - *b.
o Return.
3. Function for Multiplication
o Start.
PS & PwC Unit 4

o Dereference the pointers to calculate *result = *a * *b.


o Return.
4. Function for Division
o Start.
o If *b is not zero, dereference the pointers to calculate *result = *a / *b.
o Else, print an error message for division by zero.
o Return.
These functions have arguments but no return values
3. Program
#include <stdio.h>
// Function to add two integers using pointers
void add(int *a, int *b, int *result) {
*result = *a + *b;
}
// Function to subtract two integers using pointers
void subtract(int *a, int *b, int *result) {
*result = *a - *b;
}
// Function to multiply two integers using pointers
void multiply(int *a, int *b, int *result) {
*result = *a * *b;
}
// Function to divide two integers using pointers
void divide(int *a, int *b, int *result) {
if (*b != 0) {
*result = *a / *b;
} else {
printf("Error: Division by zero is not allowed.\n");
}
}
int main() {
int a, b;
int sum, difference, product, quotient;
// Input values for a and b
printf("Enter two integers: ");
scanf("%d %d", &a, &b);
// Perform arithmetic operations
add(&a, &b, &sum);
subtract(&a, &b, &difference);
multiply(&a, &b, &product);
divide(&a, &b, &quotient);
// Display results
printf("Sum: %d\n", sum);
printf("Difference: %d\n", difference);
printf("Product: %d\n", product);
if (b != 0) {
printf("Quotient: %d\n", quotient);
}
return 0;
}
PS & PwC Unit 4

4. Expected Output:
Enter two integers: 10 5
Sum: 15
Difference: 5
Product: 50
Quotient: 2
4. Develop a program using pointers to compute the sum of all elements stored in an
array.
1. Analysis
Problem Description:
We are tasked with computing the sum of all elements stored in an array. Instead of
using array indices, we will use pointers to access and manipulate the elements of the
array. This method allows us to work directly with memory addresses, showcasing the
flexibility of pointers in C.
Technique Chosen:
We will use pointer arithmetic to traverse through the array. A pointer will be
initialized to point to the first element of the array, and we will move the pointer
through the array to access each element and calculate the sum.
Approach:
• The pointer will point to the first element of the array.
• We will iterate through the array using the pointer, dereferencing it to access
each element.
• The sum will be updated as we go through the array.
2. Algorithm
Algorithm for main Function
1. Start.
2. Declare an integer array arr[] and an integer variable sum.
3. Input the size of the array (number of elements).
4. Input the elements of the array.
5. Call the sumArray function, passing the array and its size.
6. Display the sum.
7. Stop.
Algorithm for sumArray Function
1. Start.
2. Declare an integer pointer ptr and initialize it to point to the first element of the
array.
3. Initialize a variable sum = 0.
4. Iterate through the array:
o For each element, dereference the pointer and add the value to sum.
o Increment the pointer to move to the next element.
5. Return the sum.
6. End
3. Program
#include <stdio.h>
// Function to compute the sum of all elements in the array using pointers
int sumArray(int *arr, int size) {
int sum = 0;
int *ptr = arr; // Pointer to the first element of the array
// Iterate through the array using pointer arithmetic
for (int i = 0; i < size; i++) {
sum += *ptr; // Add the value at the current pointer location
PS & PwC Unit 4

ptr++; // Move the pointer to the next element


}
return sum;
}
int main() {
int size;
// Input the size of the array
printf("Enter the number of elements: ");
scanf("%d", &size);
int arr[size];
// Input the elements of the array
printf("Enter %d elements:\n", size);
for (int i = 0; i < size; i++) {
scanf("%d", &arr[i]);
}
// Call the sumArray function and display the result
int result = sumArray(arr, size);
printf("The sum of all elements is: %d\n", result);
return 0;
}
4. Expected Output:
Enter the number of elements: 5
Enter 5 elements:
12345
The sum of all elements is: 15
5. What is dynamic memory allocation and explain the difference between malloc ()
and calloc ().
Dynamic memory allocation refers to the process of allocating memory at runtime,
rather than at compile time. This allows for flexible memory management, enabling
programs to adapt to varying data requirements.
Feature Static Memory Allocation Dynamic Memory Allocation
Timing Compile Time Runtime
Memory Stack Heap
Location
Size Fixed Size Flexible Size
Lifetime Until Program termination or Manually deallocated using free()
function exit
Flexibility Less Flexible More Flexibile

The functions malloc () and calloc () are library functions that allocate memory
dynamically. Dynamic means the memory is allocated during runtime (execution of
the program) from the heap segment.
Initialization
malloc() (Memory Alloc) allocates a memory block of given size (in bytes) and returns
a pointer to the beginning of the block. malloc() doesn’t initialize the allocated
memory. If you try to read from the allocated memory without first initializing it,
then you will invoke undefined behaviour, which usually means the values you read
will be garbage values.
PS & PwC Unit 4

calloc() (Contiguous Alloc) allocates the memory and also initializes every byte in the
allocated memory to 0. If you try to read the value of the allocated memory without
initializing it, you’ll get 0 as it has already been initialized to 0 by calloc().
Parameters
malloc() takes a single argument, which is the number of bytes to allocate.
Unlike malloc(), calloc() takes two arguments:
1. Number of blocks to be allocated.
2. Size of each block in bytes.
Return Value
After successful allocation in malloc() and calloc(), a pointer to the block of memory is
returned otherwise NULL is returned which indicates failure.
S.No Feature malloc calloc
Allocates a single block of Allocates contiguous blocks of
1 Purpose
memory memory
2 Parameters size_t size size_t num, size_t size
Multiple blocks, each of specified
3 Memory Allocation One block of specified size
size
4 Speed Faster Slower
5 Time Efficiency High Low
6 Initialization Does not initialize memory Initializes memory to zero
May add some overhead for
7 Memory Overhead No
bookkeeping
8 Syntax void* malloc(size_t size); void* calloc(size_t num, size_t size);

6. Explain the dynamic memory allocation functions in C with an example program.


Dynamic memory allocation in C refers to the process of allocating memory at runtime, which
means that the memory size can be determined and allocated while the program is executing.
This is useful when the size of data structures like arrays is not known in advance.
In C, dynamic memory allocation is handled using the following functions:
1. malloc() (Memory Allocation)
2. calloc() (Contiguous Allocation)
3. realloc() (Reallocation)
4. free() (Deallocation)
These functions are defined in the stdlib.h header file.

1. malloc() - Memory Allocation


The malloc() function is used to allocate a block of memory of a specified size. The
syntax is:
void* malloc(size_t size);
• size: The number of bytes to allocate.
• Returns a pointer to the allocated memory, or NULL if the allocation fails.
Example:
int* ptr = (int*)malloc(5 * sizeof(int));
This allocates memory for 5 integers.

2. calloc() - Contiguous Allocation


The calloc() function is used to allocate memory for an array of elements, initializing all
bytes to zero. The syntax is:
void* calloc(size_t num_elements, size_t size_of_element);
PS & PwC Unit 4

• num_elements: The number of elements to allocate.


• size_of_element: The size of each element in bytes.
• Returns a pointer to the allocated memory, or NULL if the allocation fails.
Example:
int* ptr = (int*)calloc(5, sizeof(int));
This allocates memory for 5 integers and initializes each to 0.

3. realloc() - Reallocation
The realloc() function is used to change the size of previously allocated memory. It can
either expand or reduce the size of the memory block. The syntax is:
void* realloc(void* ptr, size_t new_size);
• ptr: The pointer to the previously allocated memory.
• new_size: The new size of the memory block in bytes.
• Returns a pointer to the reallocated memory, or NULL if the reallocation fails.
Example:
ptr = (int*)realloc(ptr, 10 * sizeof(int));
This reallocates the memory to hold 10 integers.

4. free() - Deallocation
The free() function is used to release the memory that was dynamically allocated using
malloc(), calloc(), or realloc(). The syntax is:
void free(void* ptr);
• ptr: The pointer to the memory block to be freed.
Example:
free(ptr);
This frees the memory previously allocated to ptr.
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr;
int n;
// Dynamically allocate memory for 5 integers using malloc
printf("Enter the number of elements: ");
scanf("%d", &n);
ptr = (int*)malloc(n * sizeof(int)); // malloc: allocate memory
// Check if malloc failed
if (ptr == NULL) {
printf("Memory allocation failed.\n");
return 1;
}

// Input values into the dynamically allocated memory


printf("Enter %d elements: \n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &ptr[i]);
}
// Print the values
PS & PwC Unit 4

printf("Entered elements are: \n");


for (int i = 0; i < n; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// Reallocate memory to hold 10 integers using realloc
printf("Reallocating memory to hold 10 elements.\n");
ptr = (int*)realloc(ptr, 10 * sizeof(int)); // realloc: reallocate memory
// Check if realloc failed
if (ptr == NULL) {
printf("Memory reallocation failed.\n");
return 1;
}
// Input new values into the reallocated memory
printf("Enter 5 more elements: \n");
for (int i = n; i < 10; i++) {
scanf("%d", &ptr[i]);
}
// Print all values
printf("All elements are: \n");
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
printf("\n");
// Free the dynamically allocated memory
free(ptr); // free: release memory
return 0;
}

Expected Output:
Enter the number of elements: 5
Enter 5 elements:
12345
Entered elements are:
12345
Reallocating memory to hold 10 elements.
Enter 5 more elements:
6 7 8 9 10
All elements are:
1 2 3 4 5 6 7 8 9 10

Explanation of the Program

1. Memory Allocation with malloc():


o We first allocate memory for n integers using malloc().
o The program checks if the memory allocation was successful by
verifying if the pointer is NULL.
PS & PwC Unit 4

2. Memory Input and Output:


o We input n integers into the dynamically allocated memory.
o Then, we print the entered integers.
3. Reallocation with realloc():
o The memory block is reallocated using realloc() to accommodate 10
integers.
o If reallocation is successful, we input 5 more integers into the newly
allocated space and print all the integers.
4. Deallocation with free():
o Finally, we free the dynamically allocated memory using the free()
function.

You might also like