Hello its me again with another vector class problem.
Here is my .CPP file
#include "myStringVector.hpp"
void myStringVector::reserve(int n){
if(!base){
base = allocate<myString>(n);
last = base;
limit = base+n;
}
else{
myString *p = allocate<myString>(n); //new base
myString *q = p; //new last
limit = p + n; //new limit
myString *i = uninitialized_copy(base, last, q);
destroy(i);
deallocate(base);
base = p; //update base
last = q; //update last
}
}
myStringVector::myStringVector(){
this->reserve(0);
}
myStringVector::~myStringVector(){
if(!base){
deallocate(base);
deallocate(last);
deallocate(limit);
}
else{
base = initialized_destroy(base, last);
deallocate(base);
deallocate(last);
deallocate(limit);
}
}
myStringVector::myStringVector(const std::initializer_list<myString>& list){
std::cout << list.size() << "\n";
this->reserve(list.size());
last = uninitialized_copy(list.begin(), list.end(), last);
}
int myStringVector::size() const{
return (last - base);
}
bool myStringVector::empty() const{
return (this->size() == 0);
}
myString myStringVector::operator[](int index){
return *(base+index);
}
here is my .HPP file
#ifndef MYSTRINGVECTOR_HPP
#define MYSTRINGVECTOR_HPP
#include "myString.hpp"
class myStringVector{
private:
myString *base = nullptr;
myString *last = nullptr;
myString *limit = nullptr;
public:
void reserve(int);
myStringVector();
~myStringVector();
myStringVector(const std::initializer_list<myString>&);
int size() const;
bool empty() const;
myString operator[](int);
};
#endif //MYSTRINGVECTOR_HPP_INCLUDED
also using these functions...
template<typename T>
inline T* uninitialized_copy(T const* first, T const* last, T* out)
{
while (first != last) {
construct(out, *first);
++out;
++first;
}
return out;
}
...
template<typename T>
inline T* initialized_destroy(T* first, T* last)
{
while (first != last) {
destroy(first);
++first;
}
return first;
}
...
template<typename T, typename... Args>
inline T* construct(T* p, Args&&... args)
{
return new (p) T(std::forward<Args>(args)...);
}
...
template<typename T>
inline T* allocate(int n)
{
return reinterpret_cast<T*>(::operator new(n * sizeof(T)));
}
and...
template<typename T>
inline void deallocate(T* p)
{
::operator delete(p);
}
my main does this...
{
myStringVector v;
assert(v.empty());
std::cout << "Passed default ctor" << std::endl;
myStringVector v1 {"a", "b", "c"};
myStringVector v2 {"d", "e", "f"};
std::cout << v1.size() << " " << v2.size() << "\n";
std::cout << v1[0] << v1[1] << v1[2];
}
myString is just a custom string class. It works like a normal string class.
When I run main, I am expecting v1 to hold a, b, and c. And v2 to hold d, e, and f. But this is what I get...
ap÷bp÷cp÷
so it looks like it is initializing each index with extra garbage after each character. I've tried directly initializing without using reserve() and uninitialized_copy and it works fine. However, I am required to use these confusing memory management functions by my professor. I assume I am using the functions incorrectly, but its hard to know what to fix when the compiler doesnt give me any errors.
If anyone could help me see what I am doing wrong and why I am seeing garbage values I'd really appreciate it.
Thanks!
You say
But how did you implement it?
My immediate impression is that your custom string class is copying the characters and failing to put a terminating null at the end of them.
The other key point is that you are using
cout
so you need to know how your custom string is being written. eg: if you have anoperator const char*
then that will have been picked up, and the stream output will be expecting a true C String with terminating null.see the oofString output
Where chars() is defined as:
Nothing I see in this question points to the
myStringVector
as being the source of the problem.