Page 1 of 1

reference to std::vector vs pointer to array of vectors.

Posted: Sat Oct 17, 2009 9:40 pm
by short
float sum(const vector<float>& x); // prototype

float sum(const vector<float> * x); // other prototype


Ok, so I am having trouble seeing the difference between these two. Probably because I have some deep seeded misconception about arrays and pointers.

I understand why the first one works, your passing a reference to a vector. Ok. In the second one, I get confused. If you use the second prototype, and inside the sum function you say x[0] you get a pointer to the vector array as a whole, and not the 0th (first) element in the array. If you do x[0][0] you get the first element in the vector.


Why in the second prototype do you get a pointer to an array of vectors instead of a pointer to the one single vector?

Re: reference to std::vector vs pointer to array of vectors.

Posted: Sat Oct 17, 2009 9:59 pm
by qpHalcy0n
Well, you are actually passing a pointer to a vector. This can also be said to be an "array of vectors", depending on how you want to look at it.

So, by passing the address of a vector type, that is similar to saying "an array of 1 vector". Therefore, x[0] yields you the 0'th vector. Since a vector IS an array as well, you must index into IT also: x[0][0].

Then you have "The 0th vector in x, the 0th element in vector x[0]"

In being consistent with the STL, you would say:

Code: Select all

for(int i = 0; i < x->size(); ++i)
{
        float y = x->at(i);
}

Re: reference to std::vector vs pointer to array of vectors.

Posted: Sat Oct 17, 2009 10:48 pm
by avansc
well with * you cal allocate more than just the one array
so you can have something like

vector<float> *x = (vector<float>*)malloc(sizeof(vector<float>)*X);

then when you pass x to the function you will be able to do

x[0>=x<X][y]

ps: i have never done that and dont know if it will work. but in theory it should.

Re: reference to std::vector vs pointer to array of vectors.

Posted: Sun Oct 18, 2009 11:31 pm
by Joeyotrevor
I don't think malloc and C++ classes go well together.

The vector's constructor won't be called and things will get fucked up.

Re: reference to std::vector vs pointer to array of vectors.

Posted: Mon Oct 19, 2009 9:43 am
by MarauderIIC
Joeyotrevor wrote:The vector's constructor won't be called
This.

Also, short:
(*x)[0] would probably be clearer than x[0][0], for what you're doing.

And, like always, you can reseat a pointer.

Code: Select all

vector<int> a;
sum(&a);
float sum(const vector<float> *x) {
    vector<int> b;
    x = &b;
}
If you want a pointer that behaves a bit more like a reference (can't be reseated), you would do this:

Code: Select all

float sum(vector<float>* const x) {
If you want to not be able to change the values at the address that the pointer points to, and not be able to reseat the pointer:

Code: Select all

float sum(const vector<float> * const x) {
http://www.parashift.com/c++-faq-lite/c ... l#faq-18.5 YAY CONFUSION

Also, more on the topic of your original post again:
Doing an array index x is essentially saying "get the value at memory address x + i * sizeof(type that x points to)",
which is "*(x + sizeof(type that x points to)"

So x[0] is "get the value at memory address x + 0 * size of(whatever x points to)"
Which is the same as
*x
Which is "get the value at memory address x".

If you want to do your own array operator, you could do something like

Code: Select all

*(x + 1) //lol always dereference the same spot lolololol

Re: reference to std::vector vs pointer to array of vectors.

Posted: Mon Oct 19, 2009 10:31 am
by avansc
Joeyotrevor wrote:I don't think malloc and C++ classes go well together.

The vector's constructor won't be called and things will get fucked up.
seems to work fine. i debugged it and the memory behaved nicely. soo....

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <vector.h>

void printVals(vector<float> *data)
{
	for(int a = 0;a < 5;a++)
	{
		for(int b = 0;b < data[a].size();b++)
		{
			printf("%f, ", data[a].at(b));
		}
		printf("\n");
	}
}

int main(int argc, char *argv[])
{
    vector<float> *vals = (vector<float>*)malloc(sizeof(vector<float>)*5);
	
	vals[0].push_back((float)1);
	
	vals[1].push_back((float)21);
	vals[1].push_back((float)22);
	
	vals[2].push_back((float)3);
	
	vals[3].push_back((float)41);
	vals[3].push_back((float)42);
	vals[3].push_back((float)43);

	
	vals[4].push_back((float)5);

	printVals(vals);
    return 0;
}
also, if you want it to be completely dynamic you could do this. where the constructor WILL get called.
this method you never have to define the size. well only when you make it. and you can eaily size the vector array, without changing any of the relevant functions that handle the array, as you can note the program above is limited to 5, changing the array size will not get printed when you pass it to that function, unless you change the function, or pass a extra param indicating size. this program on the bottom you can change the size of the array, pass it diffent arrays. and it will work dandy. well you can pass it any vector<float>**.

Code: Select all

#include <stdio.h>
#include <stdlib.h>

#include <vector.h>

void printVals(vector<float> **data)
{
	while(*data)
	{
		for(int b = 0;b < (*data)->size();b++)
		{
			printf("%f, ", (*data)->at(b));
		}
		printf("\n");
		data++;
	}
}

int main(int argc, char *argv[])
{
    vector<float> **vals = (vector<float>**)malloc(sizeof(vector<float>*)*5);
	
	for(int a = 0;a < 4;a++)
	{
		vals[a] = new vector<float>();
	}
	vals[4] = NULL;
	
	vals[0]->push_back((float)1);
	
	vals[1]->push_back((float)21);
	vals[1]->push_back((float)22);
	
	vals[2]->push_back((float)3);
	
	vals[3]->push_back((float)41);
	vals[3]->push_back((float)42);
	vals[3]->push_back((float)43);

	printVals(vals);
    return 0;
}
EDIT: i just wanna add that you will note that the second program only has 4 rows, the 5th is assigned to NULL.
i ran the program with not declairing it null but another vector and it worked fine, so im not sure, but im confident that it may not always work.
ex. if you get memory and its something like x,x,x,x,x,0,0,0,0,0,..... it may work. but if the memory is not zeroed out. which can happen. it may just loop on.
so just take note of that. its always best to make your series null terminating.