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;
}