+ 1
A fatal bug in my vector implementation, any solution?
I've been trying to implement my own vector (which is called vektor, and it is not supposed to much different from std::vector), but there some problems here. My program works for single dimensional vektors, but the main issue is around multi dimensional ones (like the one in the main function). HOWEVER, strangely it works on Sololearn, but when I run it on my code blocks, it returns me the code error 0xC000374. Please note that when I remove the the overloaded assignment operator, my program runs perfectly even in CodeBlocks (so this probably indicates that the problem lies in this function). Can you help me find the bug ? (This is not the complete code) https://code.sololearn.com/c8Zzm92F82Rp/?ref=app
33 Respuestas
+ 4
Ali_combination
[1/2]
Another thing that I forgot to mention is that in your pop(), erase() and clear() methods, you are manipulating the value of _size, but you are not calling the destructors of the removed elements. For your pop() method it is as simple as doing
container[_size - 1].~T();
_size -= 1;
Calling the destructor of an object is safe in itself, but you have to guarantee that it will be called only once (since the destructor itself might do things like freeing memory etc).
Also, you copy the vector a lot. This is intended by the user in the copy-constructor and assignment operator, but not in reallocation() (while pushing), erase(), resize() etc. You have to remember that copying the vectors, copies their elements. This is one reason why C++'s allocation method cannot be used here (it calls constructor/destructor on alloc/dealloc-ation, which you don't want here). To avoid this, use memmove to copy the data into the new buffer.
+ 4
Ali_combination
Sorry again for replying so late.
I was wrong in my previous answers. I gave it some thought and realised that it is actually quite horrible to mempy or memmove C++ objects. You are changing the adress of the object itself. This will have a lot of undesirable effects, like the changed value of 'this', invalidation of any references or pointers to the copied object or its fields, etc.
Turns out, you don't need to do it either. The STL implementation itself copies elements during reallocation
https://code.sololearn.com/c4gnheQCIMw4/?ref=app
If you're wondering why it copies instead of moves for movable objects, see this
https://stackoverflow.com/questions/10127603/why-does-reallocating-a-vector-copy-instead-of-moving-the-elements
Adding a noexcept specifier in the move constructor makes the compiler use it over the copy constructor
https://code.sololearn.com/ckuK0iMXS14N/?ref=app
+ 4
Ali_combination [continued]
In short, you're currently doing the right thing copying the objects, although you could benefit from the use of std::copy, since it optimizes copying of different types of memory. So you could get some performance benefit (but not significant in most cases).
+ 3
Ali_combination
I should've asked this before but, is the error a runtime error or a compiler time error? Can you send the complete error message, or atleast the text part of it?
+ 3
Ali_combination
I don't have access to CodeBlocks so I can't reproduce the error myself. I can't pinpoint the error by looking at it. Your main() function uses
1. The default constructor
2. Copy constructor
3. .push() method
4. Destructor
These types of errors are mostly a result of some undefined behaviour that's handled by some compilers and not by others. My first thought would be some memory related issue, but I don't think there's an error in those 4 methods.
It's a weird solution, but my gut feeling wants you to try and remove all 'inline' keywords and try. Apart from that, I'll suggest comparing the compiling options of msvc and codeblocks. Once I had a code that worked fine but completely broke with -O3 level optimization (I'll suggest compiling with "-O0" ("- O zero" without space) and trying). And apart from that, I don't know what to do. Btw which compiler is Codeblocks using to compile?
+ 3
There must be a problem with your CodeBlocks settings. I don't use it myself, but from your description, it's CodeBlocks specific and memory allocation warnings in particular.
I made some tweaks to fix the error messages and play around with your code to see how it behaves. you really should not mix size_t and int. Your code feels very busy... it feels more like C than C++.
I still have no clear idea on how to fix the CodeBlocks problem, though.
https://code.sololearn.com/cwug53qPAXM9/?ref=app
+ 3
Ali_combination
[2/2]
Check out std::allocator. It is the default allocator for most containers. It doesn't initialize memory itself, so it's like using C functions, but with C++ objects in mind.
https://en.cppreference.com/w/cpp/memory/allocator
+ 3
XXX
thanks for the link to std::allocator.
That's a new one for me.
It feels somewhat similar in concept to virtual doms in js. You don't do anything concrete until there is a need to actually implement stuff, but the capability to do it is ready and waiting.
It's like solving a math problem on a scratch paper instead of your actual exam paper. Then you only write the pretty solution for your professor.
You don't really have to use it, but it gives you more control.
SO discussion:
https://stackoverflow.com/questions/31358804/whats-the-advantage-of-using-stdallocator-instead-of-new-in-c
+ 2
Ali_combination
here is a good custom vector implementation tutorial
https://www.geeksforgeeks.org/program-to-create-custom-vector-class-in-c/
The advantage of vectors is that they are easy to extend and access. If you are going to implement them with mallocs and fixed sizes, they are more like arrays than vectors...
+ 2
Bob_Li Thanks, I'll check it out. And I do want to reimplement a dynamic array ! An array that's flexible in size. so that it can grow and shrink...
+ 2
Bob_Li Also I've lately implemented my vektor in the C++ way, and without C memory functions. And it just works properly. As you said, malloc() and C functions are problematic.
+ 2
Ali_combination
Try changing the return type of assignment operator to vektor& instead of void
That is,
vektor& operator=(vektor&);
(You don't need the <T> in the declaration, but you can put it. You DO need the <T> in the definition of the function)
It might be that your compiler is looking for a operator with that return type since that's the standard return type of assignment operators
+ 2
Ali_combination
or just use vector instead of wrestling with the compiler...
As a learning experiment, this is a good one.
But I think what you get out of this is in the end is that this is the hard way of doing things C++.
Lower memory footprint might not be as ideal as you might imagine if it involves a lot of memory reallocations.
This project is similar to this Youtube video:
https://m.youtube.com/watch?v=YpNCBw-cPWw
+ 1
Bob_Li it is clearly not necessary, I'm doing it as some practice.
+ 1
I can not find the bug for you, since my C++ knowledge/experience is very, very tiny.
But, as if your question have no answer or not popular, try ask or search the same question you're stucking at in many programming communites like StackOverflow(There might be many experts here to guide you), SoloLearn(This community allows you to learn coding with others:> ), etc, they will help you and tell you where is the bug if you provide the code and follow the rules..
You can post the code to the AI (such as Bard) to get the answer right away..(The result might not be accurate)..
Hope this helps..
+ 1
janky, but probably workable... although I doubt you gain any advantage implementing it like this... malloc is inherently problematic
+ 1
Ali_combination You're welcome.
Just a programming learner/(Junior) passing by.
I'll try my best to help others who may have confused at one of these 4 languages: Java, C#, C++, and Python(C++ may not count if the project is a little harder).
One day I'll learn the advanced stuff of these languages..
+ 1
Ali_combination Thanks brother 👍
I hope my recommendation solves the problem.
+ 1
Ali_combination
Sorry for the late reply. I don't understand what you're trying to do in your memmove call.
Note that the last argument is the size of the container **in bytes**, i.e. (length * sizeof(object))
+ 1
Bob_Li implementing vector was a good experience for me. I enjoyed it. However, I found out that my knowledge is still not enough to implement it well. For example, I may need a move ctor while I still do not know what a double ampersand means (like A&&). So, for now, I better acquire some more knowledge and then start rethinking about this project. I already tested my program and gave it some test cases. While it worked fine on MSVC (but didn't in CodeBlocks in some cases), I cannot use it in real situations. I expect my vektor to work in many cases but I've almost lost my hope. It is to some extent useless 😅😅 but one day when I'm better at C++, I'll sort everything out. I do want it to work in many cases.
Reimplementing a container seems useless but is of course interesting and productive, at least for me, it is so. I can learn a lot from it.