this post was submitted on 24 Sep 2023
0 points (NaN% liked)

C++

1709 readers
8 users here now

The center for all discussion and news regarding C++.

Rules

founded 1 year ago
MODERATORS
 

i was trying to create a deque, and when the function that resizes the array is excuted, it crashes with the error from the title, and when i delete the deallocate() it stops happening, what im doing wrong? code: https://pastebin.com/0yHHcLnj

you are viewing a single comment's thread
view the rest of the comments
[–] ratatosk@feddit.de 0 points 11 months ago* (last edited 11 months ago) (10 children)

Double free corruption means you deallocate some memory twice.

Let me add a question: do you really want to implement your own deque? Because there already exists one in the STL.

[–] prettydarknwild@lemmy.world 0 points 11 months ago (9 children)

im doing it to practice, if i was going to use it for a project, i would use the STL one

[–] ratatosk@feddit.de 0 points 11 months ago* (last edited 11 months ago) (8 children)

I see. Let me know if my hint doesn't take you further, then i take a closer look. It seems, that .destroy deallocates anyway and the later .deallocate deallocates the already deallocated memory again.

[–] prettydarknwild@lemmy.world 0 points 11 months ago* (last edited 11 months ago) (1 children)

that makes sense, although is kinda weird because i also did a string implementation before doing the same thing and it worked, also the c++ reference and the book that im using to learn c++ says that .destroy() only destroys the object it doesnt deallocate

[–] ratatosk@feddit.de 0 points 11 months ago (1 children)

That's btw. another error. You byte-copy the elements and Call the destructor on the original ones. This will work only, if your element's type is trivially destructible.

Given your T has an allocating constructor and therefore an deallocating destructor:

Creating a T Calls T::T() that allocates memory.

Resizing your deque Calls T::~T() by .destroy(), deallocating this memory.

Destructing your deque should destroy the elements. Thus you call the constructor once and the destructor 1+number of deque resizes.

[–] prettydarknwild@lemmy.world 0 points 11 months ago* (last edited 11 months ago) (1 children)

so, that practice of calling .destroy() and then .deallocate() is redundant and error-prone

[–] ratatosk@feddit.de 0 points 11 months ago* (last edited 11 months ago) (1 children)

If you develop or debug a container, it is useful to have a special test class for the elements that covers potential container specific errors.

struct ContainerTester {
	static int instances;
	int counter{};
	int val;
	
	ContainerTester() : ContainerTester(0) {}
	ContainerTester(int val) : val(val)
	{
		++counter;
		++instances;
	}
	~ContainerTester() {
		--counter;
		--instances;
		if (counter < 0) std::cout << "multiple destructor calls on same element" << std::endl;
		if (instances < 0) std::cout << "negative number of instances" << std::endl;
	}
};

int ContainerTester::instances{};

std::ostream& operator<<(std::ostream& o, const ContainerTester& c) {return o << c.val;}

If I run your code with ContainerTester instead of int, i get:

negative number of instances
negative number of instances
negative number of instances
negative number of instances
negative number of instances
negative number of instances
multiple destructor calls on same element
negative number of instances
double free or corruption (out)
segmentation fault

So it's more obvious that very bad things do happen :)

Oh and note, that allocator::destroy is deprecated in C++17 and was removed with C++20.

[–] prettydarknwild@lemmy.world 0 points 11 months ago (1 children)

i used tthe tester class with my code removing the .deallocate(), and although it doesnt crash, it still runs the destructor multiple times on the same element, i think its because im just pushing i into the container, and because that constructor creates an implicit conversion between int and ContainerTester, it creates a temporary object that gets destroyed once it is pushed into the deque, am i right?

[–] ratatosk@feddit.de 0 points 11 months ago* (last edited 11 months ago) (1 children)
  1. sorry that I let you down yesterday
  2. as an excuse, I have fixed and commented your code. (remember to compile it with -std=c++20)
[–] prettydarknwild@lemmy.world 0 points 11 months ago (1 children)

dont worry, i have one more question, i should initialize variables with = or with {}?

[–] ratatosk@feddit.de 0 points 11 months ago* (last edited 11 months ago)

Direct initialization is recommended over copy initialization (=).

Okay, to be fair: it's some sort of holy war, the answer depends on who you ask.

load more comments (6 replies)
load more comments (6 replies)
load more comments (6 replies)