C++ proper structure initialization
Asked Answered
I

2

6

I'm sorry to ask another newbie question, but google could'nt quite help me (or maybe I just didn't understand it).

I'm trying to code a class that is capable of storing some simple connection data. My early concept looks like the following:

struct connectionElement{
 string ip;
 SOCKET soc;
};

class ConnectionData{
 private:
  vector<connectionElement> connections;

 public:
  ConnectionData();
  ~ConnectionData();

  void addConnection(string ip, SOCKET soc);
};

void ConnectionData::addConnection(string ip, SOCKET soc) {
 connectionElement newElement;
 newElement.ip = ip;
 newElement.soc = soc;
 connections.push_back(newElement);
 return;
}

Now I've read that objects being initialized without the use of new will be delocated once the code reaches the end of scope. So since I'm a java guy and don't know shi* about memory allocation, I was wondering what the correct way'd be to to initialize the new connectionElement in addConnection().

Do I have to use new in order to prevent the data from being deleted or does the compiler assume that a stored structure might be accessed again later on? And if I use the new operator do I have to delete all the objects manually before the thread terminates or does that happen automatically?

Inject answered 16/9, 2018 at 18:8 Comment(4)
I think the better question is does the vector class copy the object or assign a pointer to it. If it dynamically copies, then no need to worry.Anhwei
Looks fine to me. In your case, since your connectionElement consists only a string (which manages its own memory) and a SOCKET (integer), there's nothing for you to worry about.Frolicsome
@Frolicsome so are there actually data types that I'd have to initialize using new in this case? And how do I know which ones require me to do so?Inject
This doesn’t address the question, but connectionElement should have a constructor that takes an ip and soc. With that, addConnection becomes connectionElement newElement(ip, soc); connections.push_back(newConnection);. Or even connections.push_back(connectionElement(ip, soc));.Cankered
A
3

Do I have to use new in order to prevent the data from being deleted or does the compiler assume that a stored structure might be accessed again later on?

No, in your snippet, the class ConnectionData owns its data member connections, and the elements in the vector are stored by value. Hence, connections is existant as long as its owning class instance exists:

void someFunctionInYourProgram()
{
    ConnectionData example{};

    example.addConection(/* ... */);

    // do stuff with the ConnectionData instance and its connections

    void doMoreStuffWith(example);

 } // Now, example went out of scope, everything is automatically cleaned up.

And if I use the new operator do I have to delete all the objects manually before the thread terminates or does that happen automatically?

If you allocate objects with new and don't pass the raw pointer returned to some smart poiter taking care of its deletion, you must indeed manually clean it up with delete. But there shouldn't be too many situation where this applies, as std::shared_ptr and std::unique_ptr are there to the rescue, and they ship with std::make_shared and std::make_unique, which even makes it obsolete to manually invoke the new operator.

One last note on this snippet

connectionElement newElement;
newElement.ip = ip;
newElement.soc = soc;
connections.push_back(newElement);

You can simplify this to

connections.push_back({ip, soc});

which might save a copy construction (if not already optimized out by the compiler).

Ambassador answered 16/9, 2018 at 18:23 Comment(0)
A
1

Your code works!

vector.push_back()

Copies the object, so a copy of the entire structure will exist in the connections vector.

Anhwei answered 16/9, 2018 at 18:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.