Tuesday

Unsafe Rust vectors

Here's the unsafe Rust vectors program that implements a vector Vec template with the <String> data type.
This program demonstrates the use of Vec<String> to store a collection of strings.
The push and pop methods are used to add and remove elements from the vector.
Indexing is used to access specific elements within the vector.
The {:?} format specifier is used to print the value of a variable in a readable format.

This Rust program is unsafe and has out-of-bounds access.
If the index 3 is out of bounds. i.e., if the vector has fewer than four elements, accessing people_names[3] would result in undefined behavior, potentially leading to memory errors or crashes.

To have safe alternative, you can achieve the same functionality using safe Rust constructs. For example, you could use the get() method on the vector to safely access elements, which returns an Option to handle out-of-bounds case.


fn main() {

    let mut people_names : Vec<String> = Vec::new();

    people_names.push("Person_Name_01".to_string());

    people_names.push("Person_Name_02".to_string());

    people_names.push("Person_Name_03".to_string());

    people_names.push("Person_Name_04".to_string());


    people_names.pop();


          // index out of bounds: the len is 3 but the index is 3

    let fourth = &people_names[3];

    println!("Fourth person is {:?}", fourth);

}

Saturday

Safe C++ example using array data structure and at member function

The safe C++ at() member function automatically checks whether array index is within the bounds of valid elements in the container, throwing an out_of_range exception if the array index is not, i.e. if the array index is greater than or equal to its array size.
The member function at() does check against bounds.
Here's a C++ program that uses the array data structure and at() member function.

#include <iostream>

#include <array>

using namespace std;


int main()

{

    array<string, 12> month_names = { "January",

                                      "February",

                                      "March",

                                      "April",

                                      "May",

                                      "June",

                                      "July",

                                      "August",

                                      "September",

                                      "October",

                                      "November",

                                      "December",

                                    };


    cout << "month_names.at(11): " << month_names.at(11) << endl;



    // terminate called after throwing an instance of std::out_of_range exception

    cout << "month_names.at(13): " << month_names.at(13) << endl;


    return 0;

}

Unsafe Rust, Rust pointers

One reason unsafe Rust exists because the underlying computer hardware is inherently unsafe.
Other reason, Rust needs to allow programmer to interact with the operating system.
Other goal of the Rust programming language to allow software engineer to work with low-level programming.

Rust has type called pointer.
Programmers can create pointers.
Use "as" to cast a reference mutable variable into their corresponding pointer type.
Change or print pointers in the unsafe block.

Example: Rust pointers
Here's the Rust program that implements a pointer using reference ampersand symbol for mutable keyword, variable name, "as" casting, pointer asterisk symbol for mutable keyword again, and data type name.

fn main() {

    let mut i = 10;

    let ptr_to_i = &mut i as *mut i32;

   

    unsafe {

        *ptr_to_i = 20;

        println!("*ptr_to_i: {}", *ptr_to_i);

    }    


    // variable i is changed by the pointer

    println!("i: {}", i);

}

Safe C++ example: stack data structure implementation

Safe C++ programming practices aim to prevent common programming errors, such as memory leaks, buffer overflows, and undefined behavior. This is often achieved through techniques like RAII (Resource Acquisition Is Initialization), smart pointers, and range-based for loops.

Example: Implementing a Stack data structure Using vector

Here's a C++ program that implements a stack using the vector container. This approach leverages RAII to automatically manage memory, making it safer than a manual stack implementation.

#include <iostream>

#include <vector>

using namespace std;


template <typename T>

class Stack {

private:

    vector<T> data;


public:

    void push(const T& value) {

        data.push_back(value);

    }


    void pop() {

        if (!isEmpty()) {

            data.pop_back();

        }

    }


    T top() const {

        return data.back();

    }


    bool isEmpty() const {

        return data.empty();

    }

};


int main() {

    Stack<int> myStack;


    myStack.push(10);

    myStack.push(20);

    myStack.push(30);


    myStack.pop();


    cout << "Top element: " << myStack.top() << endl;


    cout << "Stack empty? " << boolalpha << myStack.isEmpty() << endl;


    return 0;

}


Explanations:
* vector: This container is used to store the elements of the stack. It automatically manages memory allocation and deallocation, preventing memory leaks.
* RAII (Resource Acquisition Is Initialization): The vector's destructor is called automatically when it goes out of scope, ensuring that the memory it allocated is freed.
* Template: The Stack class is a template, making it versatile for different data types.
* Safe Operations: The push, pop, and top functions are designed to be safe. They check for empty conditions before performing operations to avoid undefined behavior.

C++ Key Safety Features:
* Memory Management: vector handles memory allocation and deallocation automatically.
* Exception Safety: The Stack class can be made exception-safe by using techniques like RAII and proper exception handling.
* Range-Based For Loops: Consider using range-based for loops for iterating over elements in a safer and more concise manner.
* Move Semantics: For performance, especially with large objects, consider using move semantics to avoid unnecessary copies.
* Custom Allocators: For specific memory management needs, you can provide a custom allocator to vector.

By following these practices, you can write more safe and more reliable C++ code.

Unsafe Rust vectors

Here's the unsafe Rust vectors program that implements a vector Vec template with the <String> data type. This program demonstrate...