Click here to Skip to main content
15,391,989 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I made a simple program that is similar to the vector<> in c++:
<pre lang="C++">
#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;

template <typename T>
class greater_than{
private:
    const T& value;
public:
    greater_than(T& val) : value(val) {}
    bool operator() (const T& val) {return val > value;}
};

template <typename T>
class scores {
private:
    T* myscores;
    int size;
public:
    T& operator[](int& i) {
        return myscores[i];
    }
    ~scores() {delete[] myscores;}
    scores() : myscores{new T[1]}, size{0} {}
    scores(initializer_list<t> vals) : myscores{new int[vals.size()]}, size{int(vals.size())} {
        copy(vals.begin(), vals.end(), myscores);
    }
    scores(scores& val) : myscores{new T[val.size]}, size{val.size} {
        for (int i = 0; i < val.size; ++i) {
            myscores[i] = val[i];
        }
    }
    
    void push_back(istream& is) {
        int values;
        while (is >> values) {
            myscores[size] = values;
            ++size;
        }
    }
    int getsize() {
        return size;
    }
    
    T* begin() const{
        return size ? &myscores[0] : nullptr;
    }
    
    T* end()  const {
        return size ? &myscores[size] : nullptr;
    }
    friend ostream& operator<<(ostream& os, scores& mys);
    
};
ostream& operator<<(ostream& os, scores<int>& mys) {
    for (int i = 0; i < mys.size; ++i) {
        os << mys.myscores[i] << " ";
    }
    return os;
}

template<typename T>
T* begin(scores<t>& x) {
    return x.size ? &x[0] : nullptr;
}

template<typename T>
    T* end(scores<t>& x) {
        return x.size ? &x[0]+x.size() : nullptr;
    }

template <typename container, typename holdresult>
holdresult sum(const container& mycon, holdresult value = 0) {
    for (auto& x : mycon)
        value += x;
    return value;
}

template <typename con, typename pred>
int countp(const con& vec, pred predicate) {
    int cnt = 0;
    for (auto x : vec)
        if (predicate(x))
            ++cnt;
    return cnt;
}
int main()
{
    scores<int> myval {0};
    while (cin) {
        myval.push_back(cin);
    }
    for (auto x : myval)
        cout << x << " ";
}


However, the problem occurs when i give it input. When i give it a little bit of numbers it works perfectly, but when i input about 10 or more, the program crashes
with a error that says: Thread 1: EXC_BAD_ACCESS (code=2, address=0x3000000038).
Can anyone tell me why??

What I have tried:

I have tried to look at my code and look online for any other people who have the problem but i cant find any solutions.
Posted
Updated 2-Nov-21 2:53am
v4

In your push_back method you have the following:
C++
myscores[size] = values;
++size;

But you cannot assume that myscores is big enough to hold whatever number of values you are entering. You must check size to see if there is any space left in myscores. If it is close to overflowing then you need to expand it to allow further entries to be added.

So start by allocating some number of cells, and set capacity to that value. Then every time you add an item, check if size is equal to capacity. If so, allocate more space and adjust the two values for the next time.
   
v2
Comments
CPallini 2-Nov-21 8:47am
   
5.
Richard MacCutchan 2-Nov-21 9:06am
   
Thanks. As you say a std::vector would be a good choice, but I suspect this is an exercise to create a new container class.
iwanttoaskquestions 3-Nov-21 5:07am
   
How do I allocate more memory on this array? Could you please explain it to me?
Richard MacCutchan 3-Nov-21 5:19am
   
The correct way to do it in C++ is by using the new and delete operators. But that would also entail copying an existing array to a new one when you need more space. You could also use the standard C library functions malloc and realloc which will do the copying for you.

Inside a class you can also overload operator new and control what happens, although that is more complicated.
iwanttoaskquestions 3-Nov-21 5:47am
   
i have remade the push_back() function, can you tell me if things are wrong:

void push_back(T& is) {
if (size >= capacity) {
capacity = capacity + 10;
scores<t> newscore;
for (int i = 0; i < size; ++i) {
newscore[i] = myscores[i];
}
myscores = new T[capacity];
for (int i = 0; i < size; ++i)
myscores[i] = newscore[i];
}
myscores[size] = is;
++size;
}
Richard MacCutchan 3-Nov-21 6:53am
   
Yes, that looks good, although before you allocate the new array for myscores you should :
delete[] myscores;

to release the existing array; this avoids memory leaks.
merano99 3-Nov-21 17:48pm
   
1. Before delete you have to copy
2. Use memcopy instead of the for loop; that goes much faster
Richard MacCutchan 4-Nov-21 4:25am
   
Read the code above.
iwanttoaskquestions 3-Nov-21 7:49am
   
oh ok thank you for the tip.
Richard already gave you the solution.
As an alternative, you could use directly a vector as container for your data. This way you wouldn't have to worry about dynamic (re-) allocation of memory, since the vector automatically grows as needed.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900