-4

So I have my class Test.H which has a struct in it.

Class Test{
    private:
        struct Data
        {
            char *first;    
            int number;      
            int count;  
        };
        Data *myStruct;

I am trying to use the myStruct in my User.C initialiser.

//User.C
#include "Test.H"
Test::Test(const char *alp){
    myStruct.number = 0; 
}

And I get an segmentation fault and error from valgrind. I figured initially that it was due to Data* myStruct being in private, but after writing a function like this below:

Data getStruct(){
    return myStruct;
}

It will still give me errors when I use it in User.C

Torched90
  • 305
  • 1
  • 3
  • 18
  • 2
    while getting segmentation fault error, look at dangerous situations using pointers. Are you using `new` and `delete` correctly? Why not replace all pointers with smart ones? Why use the pointers in the first place? Instead of `const char*` you should use `std::string` – Fureeish Sep 29 '17 at 01:47
  • @Fureeish I am using the guidelines given to me for this program. I can not change the const char*. I am only looking for understanding of how to properly use the Data struct in other functions – Torched90 Sep 29 '17 at 01:49
  • 2
    Understood. `myStruct` is a pointer in your `Test` class. You should put `myStruct = new Data()` before accesing its members. Also - `myStruct.number = 0; ` should raise an error, since the correct syntax of accessing a member through a pointer is using an arrow (`->`) operator. It should be `myStruct->number = 0;` Do you understand the difference between object allocated on the **stack** vs on the **heap accessed through pointers**? – Fureeish Sep 29 '17 at 01:52
  • @Fureeish So in the User.C I need to declare myStruct = new Data() ? Also, yes, I changed to -> since the compiler gave warning about it – Torched90 Sep 29 '17 at 01:55
  • 1
    In the constructor of a `Test` class you should allocate memory for `Data` object using `new`. Assuming that the constructor of `Test` wants to only assign `0` to a `number` variable of `myStruct`, you should firstly call `myStruct = new Data();` and then modify its values, using an arrow operator, like: `myStruct->number = 0;` Also - remember to call `delete` on `myStruct` in the destructor of `Test`. Otherwise, with every creation of a `Test` object, you will be leaking memory. I highly encourage you to learn about **smart pointers**. – Fureeish Sep 29 '17 at 02:00
  • Thank you so much. I have now `//User.C #include "Test.H" Test::Test(const char *alp){ myStruct = new Data(); myStruct.number = 0; }` – Torched90 Sep 29 '17 at 02:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155560/discussion-between-fureeish-and-torched90). – Fureeish Sep 29 '17 at 02:03

1 Answers1

0

You need to construct the struct before you can do anything with it. Calling the default constructor will initialises it's fields to 0.

You had class capitalised, that was wrong. I also don't see a reason why it has to be a pointer, so I removed that. Lastly, I added a destructor in Data so that first will be deleted. I assume it is a cstring, so I used delete[]. If it is something else, delete it in whatever manner is appropriate.

If you must have a pointer, modify the call to the constructor to use new, delete the struct in the destructor ~Test(), and reference members of myStruct with the -> operator.

class Test {
public:
    struct Data {
        const char* first;
        int number;
        int count;

        ~Data() {
            delete[] first;
        }
    };

    Test(const char *alp) {
        // Default constructor initialises struct's fields to 0.
        myStruct = Data();
        myStruct.count = 7;
    }

private:
    Data myStruct;
};
bgfvdu3w
  • 1,548
  • 1
  • 12
  • 17
  • No, default constructor will not initialize struct's members to zero. To do so you actually need to implement a constructor in the struct setting its members to zeros. – Alex Sep 29 '17 at 16:17
  • Also, calling delete [] first in the destructor may or may not be correct. We do not know how that pointer was created and used. – Alex Sep 29 '17 at 16:19
  • @Alex I've tested with GDB and found the values do get initialised to 0. [This](https://stackoverflow.com/a/8280207/5717792) answer also supports my statement. Yes, you are right about the pointer. I did state I was making an assumption about it being an array. I will edit and make it clearer. – bgfvdu3w Sep 29 '17 at 20:38
  • in Visual Studio 2015 values are not being initialized. Keep in mind also that debug and release builds may behave differently. Personally I try to stick to the practice of taking care of initialization in my code and not rely on standards which may change. – Alex Sep 30 '17 at 18:54