Custom vector class not assigning values.

Pages: 12
I'm trying to create a custom vector class.
For some reason I can't seem to get any output from my function calls and I'm not sure if it's because the vector array isn't being properly assigned values, or if the vector.at function isn't outputting correctly. It's compiling just fine at the moment. What's wrong with my code?

Relevant code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
template<typename T>
MyVector<T>::MyVector(int size){ 
 capacity = size;                        
 vtr_size = capacity;
 elements = new T[vtr_size];
 
 for(int j = size, int h = size; j >= capacity; j--, h++)
 {
  elements = (T*)realloc(elements, vtr_size* sizeof(T));
  
  if(j = capacity)
       {
       capacity = h + 1;
       } 
 }

 for(int i=0; i<vtr_size; i++)
 {
  *(elements + i) = 0;
 }
}


template<typename T>
T MyVector<T>::at(int index)
{
 if(index > vtr_size)
 {
  return '\0';
 }else{
 return elements[index];
 }
}




int main(int argc, char *argv[])
{
    MyVector<int>V1();
    
    MyVector<int>V2(5);
    
    V2.at(1);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
Can't really say what is wrong with your code, except that you are doing a lot of allocation in the constructor. From what you have posted, here is what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <cstdlib>
using namespace std;

template <typename T> class MyVector {
	T * elements;
	int size;
	public:
		MyVector(int);
		T &at(int);
};

template<typename T>
MyVector<T>::MyVector(int size) : size(size), elements(new T[size]){}


template<typename T>
T &MyVector<T>::at(int index)
{
	if(index > size)
	{
		throw "ValueError: value not found in vector";
	}
	else{
		return elements[index];
	}
}


int main(int argc, char *argv[])
{
    MyVector<int>V1();

    MyVector<int>V2(5);
	
	try { V2.at(6); }
	catch (const char * exception) { cout << exception << endl;}

    //system("PAUSE");
    return EXIT_SUCCESS;
}
Again, you cannot use realloc in combination with new.
Why and how do I fix it? Even if I comment out the line with new entirely I still get no output. Even when I create a test function that uses data entirely separate from *elements I still get no output. and it still compiles just fine no matter how i do it.
You will come to love that compiling is only half the battle in programming.

What does your test function look like?
Even if I comment out the line with new entirely I still get no output.


What kind of output are you looking for in a program that.. generates no output?
The at function is clearly supposed to output the value at elements[index] (see "return elements[index]")

The test function basically (though not word for word cause I've deleted it and rewritten it some) adds:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
....
private:
int testnum;

public:
int test(int i);
};

int MyVector<T>::test(i)
{
 testnum = i;
return i;
}


int main(...){
....
V2.test(3);
}
"
Last edited on
The at function is clearly supposed to output the value at elements[index] (see "return elements[index]")


If by, "clearly supposed to output the value" you mean is "clearly supposed to return the value," I would agree with your assessment. There is no "output" involved here.

1
2
3
4
5
6
7
8
9
#include <iostream>
// ...

int main()
{
    // ...
    std::cout << "The value returned for V2.at(3) is " << V2.at(3) << '\n' ;
    // ...
}


Now we have some output involved.
Last edited on
I will grant that that was a silly mistake.... point still stands, the MyVector(int size) function isn't initializing any elements in the elements array, regardless of the presence of new or realloc....
Last edited on
It would be silly to test that assumption if you're using realloc in combination with new. Assuming that you aren't using realloc, what makes you think it isn't assigning values to elements of your elements array?
Mostly that if I change
1
2
3
4
 for(int i=0; i<vtr_size; i++)
 {
  *(elements + i) = 0;
 }

to
1
2
3
4
for(int i=0; i<vtr_size; i++)
 {
  *(elements + i) = 4;
 }

V2.at(1);
will still return 0.
Then perhaps you can analyze the differences between your code and the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>

template <typename T>
class MyVector
{
private:
    unsigned vtr_size;
    unsigned capacity;
    T* elements;

public:
    MyVector(unsigned size, T default_value = T()) 
        : vtr_size(size), capacity(size), elements(new T[size]) 
    {
        for (unsigned i = 0; i < vtr_size; ++i)
            elements[i] = default_value;
    }

    T at(unsigned index) const 
    {
        if ( index < vtr_size) 
            return elements[index]; 

        return T();
    }

    unsigned size() const { return vtr_size; }
};

template <typename container>
void print(const container& c)
{
    for (unsigned i = 0; i < c.size(); ++i)
        std::cout << c.at(i) << ' ';
    std::cout << '\n';
}

int main()
{
    MyVector<int> V1(5);
    MyVector<int> V2(5, 4);

    print(V1);
    std::cout << '\n';

    print(V2);
    std::cout << '\n';
}


http://ideone.com/Lzk1KS
Last edited on
Real quick, what are you doing in the function definition after the arguments with
"T default_value =T())
: vtr_size(size), capacity(size), elements(new T[size])"

We haven't gone over anything like that in class, is that just the same as saying vtr_size = size, etc? And what is default_value even defined as here??
Edit: okay default_value is less confusing, but using the () op after T in the definition is still weird seeming to me. Oh wait, I'm being an idiot. Thanks for the very good reference cire.
Last edited on
Real quick, what are you doing in the function definition after the arguments with
1
2
T default_value =T())
    : vtr_size(size), capacity(size), elements(new T[size])" 

This is the constructor initialization list. It is how one initializes class members (as opposed to assigning to members in the body of the constructor.) For the purposes of this code, they are pretty much equivalent, but one should prefer to use the initialization list.

T default_value = T() sets default_value to a default constructed T (which would be 0 for an integral type) if a value isn't supplied when the constructor is called.
Last edited on
Alright, I kinda hate coming back for more when I'm making so much progress, but I'm a little stuck on my pop_back function. The problem is that when I use "free" and "realloc" on elements to reduce it's actual capacity by 1 the first few memory locations have already been overwritten by the time realloc is done.
1
2
3
4
5
6
7
8
9
10
11
template<typename T>
void MyVector<T>::pop_back()
{    
     capacity--; vtr_size--;
         
     free (elements);
     for(int i=0; i < capacity; i++)
     {
            elements = (T*)realloc(elements, vtr_size* sizeof(T));
     }
}

To get around this I simply make a temporary array with the values of element I want to keep, and recopy its information after reallocation is complete. However I seem to be running into an infinite loop or something because the program stops responding.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template<typename T>
void MyVector<T>::pop_back()
{    
     capacity--; vtr_size--;
     
     T *temp;
     for(int j = 0; j < vtr_size; ++j)
     {
             temp[j] = elements[j];
     } 
           
     free (elements);
     for(int i=0; i < capacity; i++)
     {
            elements = (T*)realloc(elements, vtr_size* sizeof(T));
     }
     
     for(int j2 = 0; j2 < vtr_size; j2++)
     {
             elements[j2] = temp[j2];
     }
delete temp;    
}

I honestly don't see what's wrong with this code....



Edit: Solved the non-class type error.
Last edited on
Still can't figure out what's wrong with my pop_back function.
Doesn't your program segfault?

What is temp pointing to?
Fixed it somewhat, but it still crashes. If I free (temp) it crashes at the same spot, if I free and delete it crashes at the same spot, if I only delete it crashed later during runtime, if I neither free nor delete it crashes when the program closes. Whats wrong now?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<typename T>
void MyVector<T>::pop_back()
{    
     capacity--; vtr_size--;
     
     T *temp = (T*) malloc (sizeof(T));
     for(int j = 0; j < vtr_size; ++j)
     {
             temp[j] = elements[j];
     } 
     
     free (elements);
     for(int i=0; i < capacity; i++)
     {
            elements = (T*)realloc(elements, vtr_size* sizeof(T));
     }  
     
     for(int j2 = 0; j2 < vtr_size; j2++)
     {
             elements[j2] = temp[j2];
     }
     free (temp); 
     //delete temp;
}
Don't know, but I think your problem is probably related to what Cire has been trying to tell you.

Why not do things the C++ way:
1
2
3
4
5
6
7
8
9
10
11
template <typename T>
void MyVector<T>::pop_back(){
    if(vtr_size==0)
        return;
    --vtr_size;
    T *temp = new T[vtr_size];
    for(unsigned i=0; i<vtr_size; ++i)
        temp[i] = elements[i];
    delete [] elements;
    elements = temp;
}
Thanks so much for this.. also helped me create my own vector class. :)
Pages: 12