Crash when copy a particular class [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I have a class really complicate, it has inside a vector of another class. I report one simpler, anyway it has inside the problem which I've been able to find.
// the inner class
class DuffyDuck{
int isblack; // 0 is white, 1 is black
int n_duck;
vector<DuffyDuck> * point_Duck;
public:
DuffyDuck(int isblack):isblack(isblack){
}
void set_point(vector<DuffyDuck> & Abitants){
point_Duck=&Abitants;
}
};
// the complessive class
class DuckCity{
vector<DuffyDuck> DuckAbitants;
public:
DuckCity(int numwhite,int numblack){
for(int i=0;i<(numblack+numwhite);++i){
DuckAbitants.push_back(DuffyDuck(i>=numblack));
DuckAbitants[i].set_point(DuckAbitants);
}
}
};
Now this works (i use point_Duck in several functions) but if I do something like that shown after once it's called in example "(*point_Duck)[2].n_duck;" in a function the project crashes.
That happens only if I do that:
DuckCity LittleTown(0,0);
LittleTown=DuckCity(3,5);
And after using some functions which call pointer.
If I do directly LittleTown(3,5) all is right.
I hope I explained well enough.

The DuffyDuck class is storing the address of a vector<> member of a DuckCity. Thus, when you copy the DuckCity to a different instance, that new instance will have a different vector<> instance. However, each DuffyDuck instance in that vector still has the address that was part of the old DuckCity instance.
So, your copy into littleTown yields dangling pointers.
I would recommend that you either rethink your design of DuffyDuck, or implement an assignment operator for DuckCity that performs a deep copy for each element of the vector<>. If you implement an assignment operator, remember to also follow the Rule of Three.

The cause of the problem is that each DuffyDuck has a pointer to a vector of DuffyDuck(s). When the class is destroyed the references become invalid --> crash.
DuckCity littleTown(1,2); // this creates a duck city
// with each duck pointing to the DuckAbitans vector.
littleTown=DuckCity(3,5); // this initializes another instance (call it INST)
// of DuckCity and
// then it assigns (via = operator) the value to littleTown
// by **copying** the DuffyDuck structures into a newly
// allocated vector. This makes the pointer of each DuffyDuck
// invalid after INST is destroyed (as it is a temporary object)

When you copy the address of Abitants, you are taking the address of the vector in the temporary object created by DuckCity(3,5). This temporary object is then copied into littleTown, and the original object destroyed. This means your original Abitats pointer is pointing at unused memory, which in turn leads to a crash.
It's hard to say exactly how you should fix this - probably by having a copy-constructor that "reconstructs" the Abitats pointer.

Related

C++ data members: Value vs. Pointer [duplicate]

This question already has answers here:
Why should I use a pointer rather than the object itself?
(23 answers)
Closed 3 years ago.
I am beginning development on a substantial personal project and wanted to ask a question regarding data members before doing so.
I am cognizant of the big differences between references and pointers. However, in my recent research, I have not found much (if any) clarification on the differences between data member values and pointers.
Consider the following two class definitions:
class A
{
private:
const std::string someString_;
};
class B
{
private:
const std::string *someString_;
};
What are the differences/nuances between the member data of classes A and B? Informed answers and relevant articles would be highly appreciated.
Similar question has been made here.
Basically, by using value you make a copy and by using pointer you hold a memory address.
A copy means that you already have an instance of the variable type and just copy its contents when you do an assignation.
A pointer means the variable can hold the memory address of an instance or null (none instance or invalid state). You can edit the value or the contents of a pointer. By modifying the value you're holding another memory address, by modifying the contents of a pointer you're actually editing the contents at that memory address.
In fact, the class A you showed, creates a std::string when it is instantiated. And the class B just has an address to a std::string.
You can play with the A's someString_ from the A's constructor. But, you should make a new std::string or pass a reference to a std::string in the B's constructor before attempt to modify the contents of B's someString_.

How default constructor knows where to initialize the default values of the data member in memory [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
From book "The first hidden argument to the constructor is the this pointer"
Now when we write like
classname object;
Is it like first memory for the object is created and address of the object is pass to default constructor so that it can initializes the values of the class.
If this is the concept for object how memory is created, is it created by the OS ?
It depends on where you write your definition:
If you define your object at global scope the linker will figure out where to place the object in the program’s data area and make sure there is enough space. The same is true for all static objects, independent of whether they are static class members or function local statics.
If you define your object as a local object in a function it will be placed on the stack. The calling conventions on the system in use will arrange for enough space on the stack (assuming there is enough space on the stack to start with; otherwise you’d get a stack overflow).
If your definition is actually a member declaration, space for the object will be made in the containing object and the new object will be placed there.
Just for completeness, when using a new expression the space is allocated on the heap and the object is places there.
Another case are thread local objects which are placed somewhere on the thread’s stack.
Note that the placement of objects applies to all constructors: the only significance of the default constructor is that you don’t pass any arguments when constructing the object.
As John mentioned in the comments, there is no explicit information in the Standard on how the memory is allocated/managed. However, assuming that no compiler optimizations take place and that you are creating an object on the stack... then this will likely happen.
Given:
void f()
{
foo x;
}
The compiler will produce something like:
void f()
{
char foo_buffer[sizeof(foo)];
new (&foo_buffer) foo()
reinterpret_cast<foo*>(foo_buffer)->~foo();
}
The space for a foo instance is reserved on the stack, then the constructor is called on that space. At the end of the scope, the destructor is called.
When an object is created, the os will Create the space.when the object is created the os automatically calls the default constructor .

What differs in the destruction of stl::unordered_map and stl::vector [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I am looking for a more in detail answer, rather than UB is UB.
I have a piece of legacy code that I know is the culprit of an exception. We previously memset a vector, and once it was changed to an unordered_map it threw an exception on destruction. What in the source code makes memsetting a vector differ from an unordered_map? They both interact with contiguous memory...
In our code we have this. (I apologize for pseudo code, but the point should still be understandable...)
class B
{
std::vector<CustomObject> vect;
};
struct STRUCT_A
{
B b;
};
Later on we do this...
STRUCT_A m_struct_a;
memset(&m_struct_a, 0, sizeof(STRUCT_A));
This works perfectly fine even if we memset an stl::container! However, if we change class B to have a map then an exception occurs on the destructor.
class B
{
std::map<CustomObject> vect;
};
So I thought it had to do with the vector being contiguous, so I changed it to an unordered_map
class B
{
std::unordered_map<CustomObject> vect;
};
An exception is still thrown on the destructor. I thought it was pretty interesting, and thought it was a good question to ask...
Yes it is indeed an act of absolute insanity to ::memset an instance of a class that contains an STL container.
Thinking more generally, you can only call memset on an object that is trivially copyable. Otherwise the behaviour of your program is undefined.
For more details on that, see http://en.cppreference.com/w/cpp/string/byte/memset and http://en.cppreference.com/w/cpp/types/is_trivially_copyable
Take a look at the source for your implementation's containers.
In libstdc++, the destructor for std::vector calls CustomObject::~CustomObject() for each element in the range [begin(), end()) and then deallocates the memory. Since you memset the vector to 0, begin() == end() == 0, the range is empty and the member's destructor is never called. Similarly, the deallocation is fine since it checks that the storage is non-null before deallocating.
In std::map, the destructor tries to walk the nodes of the _Rb_tree, which fails because the root node has null pointers. In std::unordered_map, the destructor calls __builtin_memset on the bucket array, which fails because the pointer to the array has been cleared.

First time using smart pointers, am I doing it correctly? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I have two classes. One that creates a resource, which is then sent to the other class which stores it for access by different parts of the program. What I do is:
typedef std::shared_ptr<Object> ObjectPtr;
ObjectPtr CreatorClass::Create()
{
ObjectPtr(new Object);
// ...
return ObjectPtr;
}
void StorageClass::Store(ObjectPtr obj)
{
myVector.push_back(obj);
}
ObjectPtr StorageClass::Get(int index)
{
return myVector[index];
}
My questions are:
Am I correct in using shared_ptr or should I use something else?
Should I be passing ObjectPtr by value to Store function and from Get function?
Am I correct in using shared_ptr or should I use something else?
You are correct if you need shared ownership. Otherwise you are wrong.
Should I be passing ObjectPtr by value to Store function
Yes. Although you could still do .push_back(std::move(obj)) to avoid a needless copy.
and from Get function?
Depends on whether you want to
modify the original shared_ptr in the vector, then return by non-const reference,
just observe it, then return by const reference
none of the above, i.e. get you own copy of it, then return by value.
Well, generally speaking, you are not doing it very efficiently. I see multiple issues with the code, almost close to antipattern.
Omnipresent Creators. My gosh, I hate them. What's the point of a
'creator' in your example? Why can't the object be created by the
user directly?
Store function. It has two issues. First it does nothing apart putting an element to the vector, coupled with sister get, which
simply extracts. Given that, those two functions should be sent to
meet their Creator (pun intended). Instead, myVector should be
exposed to class users. Otherwise, you are severely limiting user
experience (for instance, how would they even know if they can call
get with given index? They don't know the size of the vector!). Avoid
getters and setters.
Second issue with Store - if we imagine that Store does more than simply pushing stuff to vector, and thus it's existence is justified,
it accepts shared pointer by value. Which means, you are atomically
incrementing the counter. Performance weeps. Pass shared pointer by
reference to reduce the impact. Better yet, do not use shared
ponters. There usage is not justified in 99% cases I've seen.

Storing pointer references within a class: good programming practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
In some code I have been working on, I am passing pointers into classes that aren't necessarily managed specifically by the class to which they are passed. If the class is destroyed then I check to see if the pointer's memory has or has not already been deallocated. The problem I have is that, if a pointer is deallocated and set to NULL before the class's destructor is called then I end up with a dangling pointer. The class ends up seeing the pointer is still non-NULL and tries to delete it which causes a segmentation fault. The best solution I could think of for this is to store the pointer by reference as shown below:
class PtrReferenceClass {
public:
PtrReferenceClass(int*& i_) : i(i_) {}
void run() {
if(i == NULL)
cout << "pointer is null\n";
else
cout << "pointer isn't null\n";
}
int*& i;
};
int main() {
int* i = new int(5);
PtrReferenceClass test(i);
test.run();
delete i;
i = NULL;
test.run();
return 0;
}
As expected, the output is:
pointer isn't null
pointer is null
Ofcourse when the pointer isn't store by reference I end up with a dangling pointer.
My question is as to whether or not this is generally considered to be a good programming practice. Are there any drawbacks to this solution or is there a better convention?
It depends upon what you are trying to accomplish.
If you want the memory around for your class use C++11's std::shared_ptr everywhere instead of an int*.
If you don't need the memory around for your class use C++11's std::weak_ptr.
As far as holding onto pointers in a class, that's not bad if they're wrapped in one of C++'s pointer wrappers. You can just hang onto raw pointers, but in general you should only do that if speed is an extreme concern.
You could check for NULLness in the destructor of PtrReferenceClass. A much better alternative whould be to use a shared_ptr or really clarify ownership of i.
Agree with #Paranaix in main thread comment, as well as #ToniBig, I can't really think of a situation where you would need this. Such a thing is probably to protect against horrible programmer error. You should also keep in mind that you are storing a reference to the pointer i, and that reference will be left dangling when the pointer i goes out of scope, regardless of whether the memory i refers to has been deallocated or not. SO in conclusion, please don't do this.
All you've done is trade one lifetime problem for another. The new problem may be easier to solve... or it may not.
Now you can detect that the object is gone... as long as something has kept the pointer variable alive.
Think carefully about your variable lifetimes, and whether a reference-to-pointer (or equivalently, pointer to pointer) makes sense should become clear.
There certainly are cases where double indirection is valuable. I will leave you with a quote: "Any problem in computer science can be solved by adding another layer of indirection"
These are options :
give ownership to class and manage lifecycle inside it.plus with safe
setter method for changing it when you want. Again do it if you have to create or obtain that pointer outside,otherwise just do all inside.
only pass that pointer to methods that will use it and when
needed.void run(int* i).