Problem printing string array of a pointer and repetition of the main C++ method

Asked

Viewed 143 times

0

I have an "Element" class that has a "items" pointer, of the string type (from the string.h library), responsible for saving a reference to an array of items of the Element. Everything works fine, in case I don’t run the app within a while. However, when using while, the program stops working if I try to print the items of the element I created earlier. To be clear, what I did was exactly:

1 - Modify the element

2 - Show widget items

When displaying the items of the element, several strange characters appear on the console screen and the program stops working, without even printing the items on the screen.

Follow the class and application codes:

Class Elemento:

#include<iostream>
#include<string.h>

using namespace std;

class Elemento{

private:

    string *itens;
    int size;

public:

    Elemento(string itens[], int size){
        this->itens = itens;
        this->size = size;
    }

    void showItens(){
        for(int i = 0; i < this->size; i++){
            cout<<endl<<itens[i]<<endl;
        }
    }
};

Application code:

#include<iostream>
#include "Elemento.cpp"
#include<string.h>

Elemento *el;

bool loop = true;

int main(){
    while(loop){

        int num;

        cout<<endl<<"1 - Modificar o elemento"<<endl;
        cout<<"2 - Mostrar os itens do elemento"<<endl<<endl;
        cin>>num;

        cin.sync();

        switch(num){
            case 1:{
                int num;

                cout<<"Digite o numero de itens: "<<endl;
                cin>>num;

                string itens[num];

                for(int i = 0; i < num; i++){
                    cout<<"Digite o item: "<<i+1<<": "<<endl;
                    cin>>itens[i];
                    cin.sync();
                }

                el = new Elemento(itens,num);

                el->showItens();
                break;
            }
            case 2:{
                if(el != NULL){
                    el->showItens();
                }
                break;
            }
            case 3:{
                loop = false;
                break;
            }
        }
    }
}

Would anyone know the cause of this problem?

// Update

I redid the code using malloc. They were like this:

Class Elemento:

#include<iostream>
#include<string.h>
#include<stdlib.h>

using namespace std;

class Elemento{
    private:

        string *itens;
        int size;

    public:

        Elemento(string itens[], int size){
            this->itens = (string*)malloc(size * sizeof(string));
            this->itens = itens;
            this->size = size;
        }

        void showItens(){
            for(int i = 0; i < this->size; i++){
                cout<<endl<<itens[i]<<endl;
            }
        }
};

App class:

#include<iostream>
#include "Elemento.cpp"
#include<string.h>
#include<stdlib.h>

Elemento *el;

bool loop = true;

int main(){
    while(loop){

        int num;

        cout<<endl<<"1 - Modificar o elemento"<<endl;
        cout<<"2 - Mostrar os itens do elemento"<<endl<<endl;
        cin>>num;

        cin.sync();

        switch(num){
            case 1:{
                int num;

                cout<<"Digite o numero de itens: "<<endl;
                cin>>num;

                string *itens;
                itens  = (string *)malloc(num * sizeof(string));

                for(int i = 0; i < num; i++){
                    cout<<"Digite o item: "<<i+1<<": "<<endl;
                    cin>>itens[i];
                    cin.sync();
                }

                el = (Elemento*)malloc(sizeof(Elemento)) ;
                el = new Elemento(itens,num);

                el->showItens();
                break;
            }
            case 2:{
                if(el != NULL){
                    el->showItens();
                }
                break;
            }
            case 3:{
                loop = false;
                break;
            }
        }
    }

}

I do not know if it is necessary to use malloc inside the constructor class Element. I think the problem with my code is iterating over the item pointer. I saw in some sources that it was possible to iterate on it the same way as an array, in the form 'items[Indice]'. However, my program still stops working on that part of the program.

  • Are you saving in el, an object created on the heap, pointers to objects created on the stack (items). You would have to make the copy manually or, preferably, use a container that takes care of it, such as std::vector.

  • @C.E.Gesser, Could you indicate some text that explains the difference between heap and stack, and how this applies to POO in C++? I’m researching here about this to see if I can find something that can solve this problem.

  • You have a very good answer here at Sopt: http://answall.com/questions/3797/o-que-s%C3%A3o-e-onde-est%C3%A3o-o-stack-e-heap

1 answer

1

There are several problems in your code, I will focus only on one of them.

Here

el = new Elemento(itens,num);

You are creating an anonymous object of the Element type, and in the Element object constructor you initialize the "items" pointer to reference the "items" string array that was created in "case" 1 of the "switch" command".

Problem: As soon as the execution leaves case 1, the string array is out of place, it dies, so the object created above now has an invalid "items" pointer, pointing to an object that no longer exists. Also, most likely the memory of the string array that was destroyed in the case 1 output will be reused and overwritten, getting corrupted (in the sense that it will no longer be an array of strings, other things will be written on top). Because of this, if soon afterwards you choose option 2 to print the contents of the Element object most likely the program will behave abnormally, it will probably be canceled by error.

  • I modified the program according to what I found on the Internet about dynamic memory allocation. I used malloc to reserve space for modification. However, I think the half problem now is to iterate over the pointer 'items'.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.