0

I'm working with a template class for dynamic arrays, and my code has compiled successfully, however my get function for a given element in the dynamic array does not seem to be working. Nothing seems to be outputted whenever I output the function, but this doesn't make sense, because my size function works fine, and shows that there is indeed something within the array, I just can't output it. Can anyone help?

#include <iostream>
using namespace std;

template <class T>
class Wrapper{
private:
    T* array;
    int size;
public:
    Wrapper(){
        array = NULL;
        size = 0;
    }
    int returnSize(){
        return size;
    }
    void addEntry(string input){
        if(returnSize()==0){
            array = new string[returnSize()+1];
            array[returnSize()] = input;
            size+=1;
        }
        else{
            T* newArray = new T[returnSize()+1];
            for(int i = 0; i<returnSize(); i++){
                newArray[i] = array[i];
            }
            newArray[returnSize()] = input;
            size+=1;
            string *array = new string[returnSize()];
            array = newArray;
        }
        
    }

    bool deleteEntry(string input){
        int mySize = returnSize();
        string* testArray = new string[mySize];
        for(int i = 0; i<mySize; i++){
            if(array[i]==input){
                return true;
                break;
            }
        }
        string*newArray = new string[mySize-1];
        for(int i = 0; i<mySize; i++){
            if(array[i]!=input){
                newArray[i+=1] = array[i];
        }
        }
        delete[]array;
        array = newArray;
        return true;
        
    }
    string getEntry(int input){
        if(input>size){
            return NULL;
        }
        return this->array[input];
    }
    void operator=(const Wrapper w){
        this->size = w.returnSize();
        string *newArray = new string[size];
        for(int i = 0; i<size; i++){
            newArray[i] = w.getEntry(i);
        }
        this->array = newArray;
    }
    ~Wrapper(){
        delete[] array;
    }

};

int main(){
    Wrapper<string> w;
    w.addEntry("sam");
    w.addEntry("Josh");
    w.addEntry("tom");
    cout<<"Here"<<endl;
    cout<<w.returnSize();
    for(int i = 0; i<<w.returnSize(); i++){
        cout<<w.getEntry(i);
    }
}

Alex S.
  • 1
  • 2
  • You should output a newline at the end. The shell prompt might just overwrite your output. – Goswin von Brederlow May 09 '22 at 01:37
  • *and my code has compiled successfully, however ...* -- Secret words for "I didn't debug my program". Compiling successfully only means there are no syntax errors. It has nothing to do with whether your program has no logical bugs. – PaulMcKenzie May 09 '22 at 01:38
  • Just a style note, but using `returnSize()` everywhere internally just makes the code harder to read. Use `size` directly. You should also make the `returnSize` function `const`. – Retired Ninja May 09 '22 at 01:39
  • 1
    In `addEntry` the `string *array = new string[returnSize()];` shadows the member variable. That whole line seems to just need to go. – Goswin von Brederlow May 09 '22 at 01:39
  • `int main() { Wrapper w; w.addEntry("x"); Wrapper w2 = w; }` This will create a double-delete error. Looks like you need to read up on the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – PaulMcKenzie May 09 '22 at 01:40
  • Did you run this in a debugger? I get a segmentation fault , because the name shadowing means you never update the `array` member. After removing the offending line, it works fine. Well, almost fine; you have `i << w.returnSize()` in the final `for` where you meant `i < w.returnSize()`. – Tim Roberts May 09 '22 at 01:42
  • @PaulMcKenzie How so? I think operator= causes a memory leak instead because it doesn't delete the old array of this. `addEntry` also leaks the old array. And `deleteEntry` leaks the testArray and is totaly non-functional. – Goswin von Brederlow May 09 '22 at 01:43
  • @GoswinvonBrederlow -- `Wrapper w2 = w;` -- The function that's called is the copy constructor, not assignment operator. And to that, the `operator=` is messed up anyway, before the first line of `operator=` is executed. This is because `Wrapper` is passed by value, thus invoking the copy constructor. – PaulMcKenzie May 09 '22 at 01:44
  • @PaulMcKenzie I guess I know why g++ says: *warning: implicitly-declared ‘constexpr Wrapper >::Wrapper(const Wrapper >&)’ is deprecated [-Wdeprecated-copy] note: because ‘Wrapper >’ has user-provided ‘void Wrapper::operator=(Wrapper) [with T = std::__cxx11::basic_string]’* – Goswin von Brederlow May 09 '22 at 01:54

1 Answers1

0

Just to collect the findings, if you delete this line from addEntry:

           string *array = new string[returnSize()];

and change your final for loop to:

    for(int i = 0; i < w.returnSize(); i++){
        cout<<w.getEntry(i)<<"\n";
    }

then this does exactly what you expect. I've run it myself.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30