Tuesday, April 17, 2018

unique_ptr to Save the Day

#include <iostream>
#include <memory>
#include<time.h>

void processElements(std::unique_ptr<int[]> &, int);

int main(int argc,char *args[]){
    int elements;
    srand(time(0));
    do{
    std::cout<<"Enter the number of items you'd like to store: ";
    std::cin>>elements;
    if(!std::cin){
        std::cin.clear();
    std::cin.ignore(50,'\n');
    }
    else
        continue;
    }while(elements<1);

    std::unique_ptr<int[]> values(new int[elements]);

    for (int i = 0; i < elements; ++i) {
        values[i] = (i == 0) ? 1 : rand()%10+1;
    }

    for (int i = 0; i < elements; ++i) {            //before function call
        std::cout << i << ": " << values[i] << '\n';
    }
    processElements(values,elements);
    for (int i = 0; i < elements; ++i) {            //after function call
        std::cout << i << ": " << values[i] << '\n';
    }

    return 0;
}

void processElements(std::unique_ptr<int[]> &toProcess, int size){
    srand(time(0));
        for (int i = 0; i < size; ++i) {
        toProcess[i] = (i == 0) ? 1 : rand()%10+1;
    }

    for (int i = 0; i < size; ++i) {
        std::cout << i << ": " << toProcess[i] << '\n';
    }
}

Monday, April 16, 2018

Pointers the evil problems

Errors in code to fix  - don't cheat, but the answer is also on this page.  Try to use your debugger to isolate and to locate the errors.  Copy/paste this code and find the problems.

#include <iostream>
using namespace std;

int main(int argc, char **args){
    int *ptr, *current;
    const int SIZE = 5;
    ptr = new int[SIZE];
    int value[SIZE];
    ptr = current = value;

    for (int i = 0; i <= SIZE; i++)
        value[i] = i * 2;
    for (int i = 0; i < SIZE; i++) {
        cout << *ptr << endl;
        ptr++;
    }

    cout << *(--ptr) << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << *current << endl;
        current++;
    }
  
    cout << *(ptr) << endl;
    cout << *(--current) << endl;

    for (int i = 0; i <= SIZE; i++)
        *(ptr++) = i * 2;
  
    for (int i = 0; ptr <= &value[SIZE - 1]; ptr += 1)
        *ptr = i++ * 2;
    ptr--;
    cout << "The value where pointer 'ptr' pointing to is:  " << *ptr << endl;
  
    return 0;
}







Solution
#include <iostream>
using namespace std;

int main(int argc, char **args) {
    int *ptr, *current;
    const int SIZE = 5;
    ptr = new int[SIZE];
    int value[SIZE];
    ptr = current = value;

    for (int i = 0; i < SIZE; i++)
        value[i] = i * 2;
    for (int i = 0; i < SIZE; i++) {
        cout << *ptr << endl;
        ptr++;
    }
   
    cout << *(--ptr) << endl;
    for (int i = 0; i < SIZE; i++) {
        cout << *current << endl;
        current++;
    }
   
    cout << *(ptr) << endl;
    cout << *(--current) << endl;
    ptr = value;                    //fix 2 - reset ptr to base address
    for (int i = 0; i < SIZE; i++)  //fix 3 - invalid index value
        *(ptr++) = i * 2;
   
   
    for (int i = 0; ptr <= &value[SIZE - 1]; ptr += 1)
        *ptr = i++ * 2;
    ptr--;
    cout << "The value where pointer 'ptr' pointing to is:  " << *ptr << endl;

    return 0;
}

Vector passing to function by reference and by pointer

#include<vector>
#include<iostream>

using namespace std;

bool setValues(vector<int> &base, vector<int> &compare);
bool setValues(vector<int> *base, vector<int> *compare);

int main(){
    vector<int> vect1;
    vector<int> vect2;
    vect1.push_back(10);
    vect1.push_back(20);
    vect1.push_back(30);

    if (setValues(vect1, vect2))
        cout << "They are equal" << endl;
    else
        cout << "They are not equal" << endl;

    if (setValues(&vect1, &vect2))
        cout << "They are equal" << endl;
    else
        cout << "They are not equal" << endl;


    for (int value:vect1)
        cout << value << " ";

    return 0;
}
bool setValues(vector<int> &base, vector<int> &compare) {
    bool isEqual = true;
    compare.push_back(10);
    compare.push_back(20);
    compare.push_back(30);
    for (int i = 0; i < base.size();i++) {
        if (base.at(i) != compare.at(i))
            return false;
    }
}

bool setValues(vector<int> *base, vector<int> *compare) {
    bool isEqual = true;
    (*compare).push_back(10);
    (*compare).push_back(20);
    (*compare).push_back(30);
    for (int i = 0; i < (*base).size(); i++) {
        if ((*base).at(i) != (*compare).at(i))
            return false;
    }
}

Monday, April 9, 2018

C++ and vector dynamic expansion



How Does the capacity changes as the size increases?  Well, this simple test code and chart will clear up the questions.

// This program demonstrates the vector size member function.
#include <iostream>
#include <vector>
#include<cmath>
#include<fstream>
 
using namespace std;
 
int main() {
 ofstream outFile;
 outFile.open("c:\\temp\\analysis.csv");
 vector<int> values;
 cout << typeid(values).name() << endl;
 outFile << "size, capacity, diff, count" << endl;
 // Put a series of numbers in the vector.
 for (int count = 0; count < 20; count++) {
  values.push_back(count * 2);
  outFile << values.size() << "," << values.capacity() << ","
   << abs((int)(values.size() - values.capacity()))
   << "," << count << endl;
 }
 vector<int> temp;
 for (int i : values)         //even copying based on size value will increment capacity beyond size  
  temp.push_back(i);
 values.shrink_to_fit();     //size will match capacity
 outFile.close();
 return 0;
}



This same kind of effect can be observed with string as well.


// This program demonstrates the vector size member function.
#include <iostream>
#include <vector>
#include<cmath>
#include<fstream>
#include<string>
 
using namespace std;
 
int main() {
 ofstream out("c:\\temp\\out.csv");
 string item = "a";
 out << "count,size,capacity" << endl;
 cout <<"1,"<<item.size() << "," << item.capacity() << "," << endl;
 for (int i = 2; i < 1000; i++) {
  item += "a";
  out <<i<<"," << item.size() << "," << item.capacity() << "," << endl;
 }
 out.close();
 return 0;
}