Week 8 Lecture Code
// Pantea Aria
// sizeof
#include <stdio.h>
struct student {
int id;
char grade;
double mark;
};
int main(void) {
printf("Size of an int: %lu bytes\n", sizeof(int));
printf("Size of a char: %lu bytes\n", sizeof(char));
printf("Size of a double: %lu bytes\n",sizeof(double) );
printf("Size of 5 doubles: %lu bytes\n", 5 * sizeof(double));
printf("Size of struct student: %lu bytes\n", sizeof(struct student));
printf("Size of a pointer of double: %lu bytes\n", sizeof(double *));
return 0;
}
// Pantea Aria
// static memories - they get released once the program finishes.
// you can allocate memory whenever you want and free that whenver you want - Dynamic memory
// malloc to allocate dynamic memory
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct student {
int zid;
double marks;
};
struct point {
int x, y;
};
int main(void) {
// grab dynamic memory for one integer
// allocating 4 bytes of heap and return the address into p from stack memory
int *p = malloc(sizeof(int));
// assign 20 to that memory from head
// dereferencing
*p = 20;
// print the value in the memory
printf("the value is %d\n", *p); //20
// if you don't need that memory, then release it
free(p);
// *p = 90; // INVALID
// dynamic array of int
// 10 integer after each other in heap
p = malloc(10 * sizeof(int));
// assign 10 to 19 to them
for(int i = 10; i < 20; i++) {
p[i - 10] = i;
}
// print out all values in the array
int i = 0;
while (i < 10) {
printf ("%d ", p[i]);
i++;
}
free(p);
// dynamic structure from heap
// define struct student before main
// allocate memory from heap for 1 student
struct student *q = malloc(sizeof(struct student));
// assign value to zid - dereferencing a pointer to structure
q->zid = 123456;
// assign value to marks
q->marks = 56.6;
// print out the values
printf("%d %lf", q->zid, q->marks);
// release it
free(q);
// allocate memory for one character
char *ch = malloc(sizeof(char));
// assign some value to it
*ch = 'A';
// check if upper or lowercase and print out
if (isupper(*ch)) {
printf("\n%c is upper\n", *ch);
} else {
printf("\n%c is lower", *ch);
}
free(ch);
// dynamic structure
// struct point - create a dynamic point (x, y) with a function,
struct point *st = malloc(sizeof(struct point));
// print x, y with another function
st->x = 10;
st->y = 9;
printf("x and y are %d and %d\n", st->x, st->y);
free (st);
// allocate memory for 5 points
st = malloc(5 * sizeof(struct point));
if (st == NULL) {
return 1;
}
st[0].x = 8;
st[0].y = 0;
// have a loop st[i].x , ....
return 0;
}
// Pantea Aria
// Memory Leak Example (Lost Pointer)
// Complete the TODO sections below
// (Memory is allocated twice but only one freed)
// use "dcc --leak-check program_name.c -o program" to see the error message
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// TODO 1:
// Allocate memory for one integer
int *ptr = malloc(sizeof(int));
// TODO 2:
// Store the value 10 in the allocated memory
*ptr = 10;
// TODO 3:
// Allocate NEW memory to ptr again
ptr = malloc(sizeof(int));
// TODO 4:
// Explain in a comment:
// What happened to the first allocated memory?
// TODO 5:
// Free the memory currently pointed to by ptr
free (ptr);
return 0;
}
// Pantea Aria
// Example: creating a dynamic array with malloc
// then growing it later using realloc
#include <stdio.h>
#include <stdlib.h>
// TODO: write a function that creates and returns
// a malloced array of given size
int *build_array(int size);
// TODO: write a function to print an array
void show_array(int array[], int size);
int main(void) {
int size;
printf("Enter initial size: ");
scanf("%d", &size);
// TODO: call build_array and check for NULL
int *numbers = build_array(size);
int i = 0;
while (i < size) {
numbers[i] = i * 2; //or any other value you want
i++;
}
// TODO: print the original array
show_array(numbers, size);
// We decide the array needs to grow
int new_size = size + 1;
// TODO: use a temporary pointer with realloc
int *temp = realloc(numbers, new_size * sizeof(int));
// TODO: check if realloc failed
// if successful, update numbers
if (temp != NULL) {
numbers = temp;
} else {
printf("ERROR in realloc");
free(numbers);
return 1;
}
// TODO: assign a value to the new element
numbers[new_size - 1] = 99;
// TODO: print the resized array
show_array(numbers, new_size);
free(numbers);
// TODO: free the memory
return 0;
}
int *build_array(int size) {
int *p = malloc(size * sizeof(int));
return p;
}
void show_array(int numbers[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf ("\n");
}
// Pantea Aria
// malloc and array example
#include <stdio.h>
#include <stdlib.h>
// Function prototypes
int *allocate_marks(int size);
void print_marks(int marks[], int size);
int main(void) {
int size;
printf("Enter number of marks: ");
scanf("%d", &size);
// TODO 1:
// Call allocate_marks and store the returned pointer
int *marks = allocate_marks(size);
// TODO 2:
// Check if marks is NOT NULL
if (marks == NULL) {
return 1;
}
// If it is valid:
// - Call print_marks
print_marks(marks, size);
// - Free the allocated memory
// free(marks);
return 0;
}
// This function should:
// - Allocate memory for 'size' integers
// - Check if malloc returned NULL
// - Initialise each element with some value
// - Return the pointer
int *allocate_marks(int size) {
// TODO 3:
// Allocate memory using malloc
int *p = malloc(size * sizeof(int));
// TODO 4:
// Check if memory allocation failed
// If so, print "Out of memory" and return
if (p == NULL) {
printf("Out of memory\n");
return NULL;
}
// TODO 5:
// Use a loop to initialise each element
// Example idea: p[i] = i * 2;
int i = 0;
while (i < size) {
p[i] = i * 2; //or any other value you want
i++;
}
// TODO 6:
// Return the pointer
return p;
}
// This function should print all elements
void print_marks(int marks[], int size) {
// TODO 7:
// Use a loop to print each element on a new line
for (int i = 0; i < size; i++) {
printf("%d ", marks[i]);
}
printf("\n");
}
// Pantea Aria
// Dynamically allocate a struct and return a pointer
// Complete the TODO sections below
// this program is not completed.
#include <stdio.h>
#include <stdlib.h>
struct book {
int id;
int pages;
};
// Function prototypes
struct book *create_book(int id, int pages);
void print_book(struct book *b);
int main(void) {
// TODO 1:
// Create a book with id 101 and 250 pages
struct book *b1 = create_book(101, 250);
// TODO 2:
// Print the book details
print_book(p);
// TODO 3:
// Create another book with id 202 and 300 pages
struct book *b2 = NULL; // your turn
// TODO 4:
// Print the second book
// TODO 5:
// Free both allocated books before program ends
return 0;
}
// This function should:
// - Allocate memory for a struct book
// - Check if malloc returned NULL
// - Initialise the fields
// - Return the pointer
struct book *create_book(int id, int pages) {
// TODO 6:
// Allocate memory using malloc
struct book *p = malloc(sizeof(struct book));
// TODO 7:
// Check if allocation failed
// If NULL, print "Out of memory" and exit
// you do this
// TODO 8:
// Set the struct fields using ->
p->id = id;
p->pages = pages;
// TODO 9:
// Return the pointer
return p;
}
// This function should print book details
// Format: Book ID: __, Pages: __
void print_book(struct book *b) {
// TODO 10:
// Print the struct fields using ->
printf("id is %d and pages is %d", b->id, b->pages);
}
// Pantea Aria
// Multi-File Programs
// Another program that reuses the same
// array_functions module.
// Every program has exactly one main function
// This is where the program starts and where we
// call functions from our modules.
//
// To compile the program:
// dcc -o another_mfp another_mfp.c array_functions.c
//
// To run:
// ./another_mfp
#include <stdio.h>
// Include our own header file
#include "array_functions.h"
#define MAX_SIZE 4
int main(void) {
int numbers[MAX_SIZE] = {2, 4, 6, 8};
int total = sum_array(MAX_SIZE, numbers);
if (total == 20) {
printf("Correct sum!\n");
} else {
printf("Something went wrong\n");
}
return 0;
}
// Pantea Aria
// Implementation file for the array_functions module
#include <stdio.h>
#include "array_functions.h"
// Reads integers into the given array
// Assumes valid input
void read_array(int size, int array[]) {
for (int i = 0; i < size; i++) {
scanf("%d", &array[i]);
}
}
// Prints all integers in the given array
void print_array(int size, int array[]) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
// Finds and returns the minimum value in the array
int find_minimum(int size, int array[]) {
int min = array[0];
for (int i = 1; i < size; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
}
// Returns the sum of all elements in the array
int sum_array(int size, int array[]) {
int total = 0;
for (int i = 0; i < size; i++) {
total += array[i];
}
return total;
}
// Pantea Aria
// Multi-File Programs
// Header file for the array_functions module
// Header files typically include:
// - #define constants
// - struct definitions
// - enum definitions
// - function prototypes and documentation comments
// Reads integers into the given array
// Assumes valid input
void read_array(int size, int array[]);
// Prints all integers in the given array
void print_array(int size, int array[]);
// Finds and returns the minimum value in the array
int find_minimum(int size, int array[]);
// Returns the sum of all elements in the array
int sum_array(int size, int array[]);
// Pantea Aria
// sizeof
#include <stdio.h>
struct student {
int id;
char grade;
double mark;
};
int main(void) {
printf("Size of an int: %lu bytes\n", sizeof(int));
printf("Size of a char: %lu bytes\n", sizeof(char));
printf("Size of a double: %lu bytes\n", sizeof(double));
printf("Size of 5 doubles: %lu bytes\n", 5 * sizeof(double));
printf("Size of struct student: %lu bytes\n", sizeof(struct student));
printf("Size of a pointer: %lu bytes\n", sizeof(double *));
return 0;
}
// Pantea Aria
// static memories - they get released once the program finishes.
// you can allocate memory whenever you want and free that whenver you want - Dynamic memory
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
// grab dynamic memory for one integer
// allocating 4 bytes of heap and return the address into p from stack memory
// assign 20 to that memory from head
// dereferencing
// print the value in the memory
// if you don't need that memory, then release it
// dynamic array of int
// 10 integer after each other in heap
// assign 10 to 20 to them
// print out all values in the array
// dynamic structure from heap
// define struct student before main
// allocate memory from heap for 1 student
// assign value to zid - dereferencing a pointer to structure
// assign value to name
// print out the values
// release it
// array of 10 student
return 0;
}
// Pantea Aria
// Memory Leak Example (Lost Pointer)
// Complete the TODO sections below
// (Memory is allocated twice but only one freed)
// use "dcc --leak-check program_name.c -o program" to see the error message
#include <stdio.h>
#include <stdlib.h>
int main(void) {
// TODO 1:
// Allocate memory for one integer
int *ptr = ?
// TODO 2:
// Store the value 10 in the allocated memory
// TODO 3:
// Allocate NEW memory to ptr again
// TODO 4:
// Explain in a comment:
// What happened to the first allocated memory?
// TODO 5:
// Free the memory currently pointed to by ptr
return 0;
}
// Pantea Aria
// Example: creating a dynamic array with malloc
// then growing it later using realloc
#include <stdio.h>
#include <stdlib.h>
// TODO: write a function that creates and returns
// a malloced array of given size
int *build_array(int size);
// TODO: write a function to print an array
void show_array(int array[], int size);
int main(void) {
int size;
printf("Enter initial size: ");
scanf("%d", &size);
// TODO: call build_array and check for NULL
int *numbers = /* TODO */;
// TODO: print the original array
show_array(/* TODO */);
// We decide the array needs to grow
int new_size = size + 1;
// TODO: use a temporary pointer with realloc
int *temp = /* TODO */;
// TODO: check if realloc failed
// if successful, update numbers
// TODO: assign a value to the new element
// TODO: print the resized array
// TODO: free the memory
return 0;
}
// Pantea Aria
// malloc and array example
#include <stdio.h>
#include <stdlib.h>
// Function prototypes
int *allocate_marks(int size);
void print_marks(int marks[], int size);
int main(void) {
int size;
printf("Enter number of marks: ");
scanf("%d", &size);
// TODO 1:
// Call allocate_marks and store the returned pointer
int *marks = NULL;
// TODO 2:
// Check if marks is NOT NULL
// If it is valid:
// - Call print_marks
// - Free the allocated memory
return 0;
}
// This function should:
// - Allocate memory for 'size' integers
// - Check if malloc returned NULL
// - Initialise each element with some value
// - Return the pointer
int *allocate_marks(int size) {
// TODO 3:
// Allocate memory using malloc
// TODO 4:
// Check if memory allocation failed
// If so, print "Out of memory" and return NULL
// TODO 5:
// Use a loop to initialise each element
// Example idea: marks[i] = i * 2;
// TODO 6:
// Return the pointer
}
// This function should print all elements
void print_marks(int marks[], int size) {
// TODO 7:
// Use a loop to print each element on a new line
}
// Pantea Aria
// Dynamically allocate a struct and return a pointer
// Complete the TODO sections below
#include <stdio.h>
#include <stdlib.h>
struct book {
int id;
int pages;
};
// Function prototypes
struct book *create_book(int id, int pages);
void print_book(struct book *b);
int main(void) {
// TODO 1:
// Create a book with id 101 and 250 pages
struct book *b1 = NULL;
// TODO 2:
// Print the book details
// TODO 3:
// Create another book with id 202 and 300 pages
struct book *b2 = NULL;
// TODO 4:
// Print the second book
// TODO 5:
// Free both allocated books before program ends
return 0;
}
// This function should:
// - Allocate memory for a struct book
// - Check if malloc returned NULL
// - Initialise the fields
// - Return the pointer
struct book *create_book(int id, int pages) {
// TODO 6:
// Allocate memory using malloc
// TODO 7:
// Check if allocation failed
// If NULL, print "Out of memory" and exit
// TODO 8:
// Set the struct fields using ->
// TODO 9:
// Return the pointer
}
// This function should print book details
// Format: Book ID: __, Pages: __
void print_book(struct book *b) {
// TODO 10:
// Print the struct fields using ->
}
// Pantea Aria
// Multi-File Programs
// Another program that reuses the same
// array_functions module.
// Every program has exactly one main function
// This is where the program starts and where we
// call functions from our modules.
//
// To compile the program:
// dcc -o another_mfp another_mfp.c array_functions.c
//
// To run:
// ./another_mfp
#include <stdio.h>
// Include our own header file
#include "array_functions.h"
#define MAX_SIZE 4
int main(void) {
int numbers[MAX_SIZE] = {2, 4, 6, 8};
int total = sum_array(MAX_SIZE, numbers);
if (total == 20) {
printf("Correct sum!\n");
} else {
printf("Something went wrong\n");
}
return 0;
}
// Pantea Aria
// Implementation file for the array_functions module
#include <stdio.h>
#include "array_functions.h"
// Reads integers into the given array
// Assumes valid input
void read_array(int size, int array[]) {
for (int i = 0; i < size; i++) {
scanf("%d", &array[i]);
}
}
// Prints all integers in the given array
void print_array(int size, int array[]) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i]);
}
printf("\n");
}
// Finds and returns the minimum value in the array
int find_minimum(int size, int array[]) {
int min = array[0];
for (int i = 1; i < size; i++) {
if (array[i] < min) {
min = array[i];
}
}
return min;
}
// Returns the sum of all elements in the array
int sum_array(int size, int array[]) {
int total = 0;
for (int i = 0; i < size; i++) {
total += array[i];
}
return total;
}
// Pantea Aria
// Multi-File Programs
// Header file for the array_functions module
// Header files typically include:
// - #define constants
// - struct definitions
// - enum definitions
// - function prototypes and documentation comments
// Reads integers into the given array
// Assumes valid input
void read_array(int size, int array[]);
// Prints all integers in the given array
void print_array(int size, int array[]);
// Finds and returns the minimum value in the array
int find_minimum(int size, int array[]);
// Returns the sum of all elements in the array
int sum_array(int size, int array[]);
// Pantea Aria
// // Multi-File Programs
// Every program has exactly one main function
// This is where the program starts and where we
// call functions from our modules.
//
// To compile the program:
// dcc -o mfp mfp.c array_functions.c
//
// To run:
// ./mfp
#include <stdio.h>
// Include our own header file using ""
#include "array_functions.h"
#define MAX_SIZE 5
int main(void) {
int numbers[MAX_SIZE];
printf("Enter %d integers: ", MAX_SIZE);
read_array(MAX_SIZE, numbers);
printf("Array contents: ");
print_array(MAX_SIZE, numbers);
int min = find_minimum(MAX_SIZE, numbers);
printf("Minimum value: %d\n", min);
int total = sum_array(MAX_SIZE, numbers);
printf("Sum of elements: %d\n", total);
return 0;
}
// Pantea Aria
// // Multi-File Programs
// Every program has exactly one main function
// This is where the program starts and where we
// call functions from our modules.
//
// To compile the program:
// dcc -o mfp mfp.c array_functions.c
//
// To run:
// ./mfp
#include <stdio.h>
// Include our own header file using ""
#include "array_functions.h"
#define MAX_SIZE 5
int main(void) {
int numbers[MAX_SIZE];
printf("Enter %d integers: ", MAX_SIZE);
read_array(MAX_SIZE, numbers);
printf("Array contents: ");
print_array(MAX_SIZE, numbers);
int min = find_minimum(MAX_SIZE, numbers);
printf("Minimum value: %d\n", min);
int total = sum_array(MAX_SIZE, numbers);
printf("Sum of elements: %d\n", total);
return 0;
}