LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-06-2003, 03:21 AM   #1
qanopus
Senior Member
 
Registered: Jul 2002
Location: New York
Distribution: Slackware
Posts: 1,358

Rep: Reputation: 45
getting size of an array in c++


Hi there. I want to make an function that calculates the vector product of two vectors. Something like

Code:
int dotProd(int *v1, int *v2)
{
     // we can define them as integers because the vectors contain only 
     // integer values

     int size = somehowgetsize(v1);
     int i;
     int prod = 0;

     for(i=0;i<=size;i++)
     {
           prod += v1[i] * v2[i];
     }

     return prod;

}
So how do I define the function "somehowgetsize"?

Last edited by qanopus; 11-06-2003 at 03:23 AM.
 
Old 11-06-2003, 03:32 AM   #2
gradedcheese
Member
 
Registered: Nov 2003
Posts: 59

Rep: Reputation: 15
hmm... I am weird so I normally don't do stuff like this with arrays. Instead I'll create a simple linked list object, with the last element having the usual NULL next-element-pointer. I then pass the address of the list's head nodes to the function you're writing rather than the addresses of arrays. To calculate the length of a linked list you can simply traverse it and keep count of nodes (you stop of course when you hit that NULL next element pointer). Or you can have the list object have a function that returns the size.
 
Old 11-06-2003, 04:09 AM   #3
cdlen
Member
 
Registered: Oct 2003
Location: EU
Distribution: RH7.2 Mdk9.2
Posts: 39

Rep: Reputation: 15
the classical way of getting the number of elements in an array is:
sizeof (array)/ sizeof(elem)
But when the array is passed as a pointer, sizeof(array) returns the size of a pointer !
That's the strength and weakness of the C language. A pointer is a pointer is pointer... The compiler has no way to know what the pointer refers to. That provides a convenient way to switch the objects a pointer is pointing to but then it is your entire responsability of knowing what it is referring to. Just look at Windows api (must be the same for Linux) : all those structures passed as arguments. Each time the structure has an element to give the size of the structure.
Looking at Stroustrup's (p147): an array can't be passed by value in a function's arguments. Ways around:
When you got a zero-terminated string array it's easy to get the length.
Or you pass the number of elements as well
Or use standard lib vector type (which do the same thing only automatically)

If you have used other higher-level languages like Python,.. that must look tedious but don't forget that the objects they manage store their length inside them.
When you work with C you are as close as possible to the brass metal; when you ask for an array of 5 elements you got just that: 5 memory cells no more no less. And a pointer can point to anything (or be made to); if you use the pointer of the array to access a 6th inexistent element nobody's there to tell you you are getting in big troubles...
 
Old 11-06-2003, 06:23 AM   #4
mr_segfault
Member
 
Registered: Oct 2003
Location: Australia
Distribution: Redhat 9
Posts: 95

Rep: Reputation: 15
schatoor & gradedcheese,

I would suggest that you dont use arrays, nor create your own linked list class (well not if your using c++ anyway). The STL has some great containers (including linked list) that will do what you want much better.

Incase you dont know, the STL is part of the C++ standard is part of your c++ library.. (with most modern compilers)


Code:
#include <vector>

int dotProd(std::vector<int> &v1, std::vector<int> &v2)
{
  // we can define them as integers because the vectors contain only 
  // integer values

  int size = v1.size(); // this code assumes that v2 is atleast as large as v1
                        // therefore its not so good!
  int i;
  int prod = 0;

  for(i=0;i<size;++i) // note I changed i<=size to i<size, the former would explode :) see note below.
  {
    prod += v1[i]  * v2[i];
  }

  return prod;
}

void dummyFunc()
{
  // create two vectors
  std::vector<int> myVec1;
  std::vector<int> myVec2;

  // set their size
  myVec1.resize(4);
  myVec2.resize(4);

  // set some values.
  myVec1[0] = 22;
  myVec1[1] = 2;
  myVec1[2] = 34;
  myVec1[3] = 8;

  myVec2[0] = 6;
  myVec2[1] = 7;
  myVec2[2] = 73;
  myVec2[3] = 11;

  // do the work
  int theDotProduct = dotProd(myVec1, myVec2);
}
Note: Because of these type of errors, it is often best to use iterators to traverse through containers, since they eliminate these types of 'past the end' errors..

std::vectors are nice since they allow indexing like arrays (the operator[] is overloaded to return a reference to the item at the specified location)

Depending on what you are actually doing, you might want to look as using the vector's push_back() method instead of size() and operator[]. push_back adds an element to the vector (increases its size by 1) and assigns the value you pass to it. Like :myVec1.push_back(10); will add the int '10' to the said vector..

For some good reference material see this thread where I posted some good links: Good reference material for C++

I hope that helps.

Cheers.
 
Old 11-06-2003, 06:41 AM   #5
qanopus
Senior Member
 
Registered: Jul 2002
Location: New York
Distribution: Slackware
Posts: 1,358

Original Poster
Rep: Reputation: 45
Wow, cool guy's, thanks for the detaild answers.
I my self thought of an solution along the lines of what cdlen said. I made an c++ vector class with an member var. indicating the size of the vector. But mr_segfault solution seems better.
Thanks again for all the help.
 
Old 11-06-2003, 08:55 AM   #6
dakensta
Member
 
Registered: Jun 2003
Location: SEUK
Distribution: Debian & OS X
Posts: 194

Rep: Reputation: 35
Another alternative (depending on your use of the vector class - i.e. it is not going to change size):

Code:
template<typename T, size_t N>
struct Vector
{
	T val[N];
	T& operator[] ( size_t i ) { return val[i]; }
	const T& operator[] ( size_t i ) const { return val[i]; }
};

template<typename T, size_t N>
T dot_prod( const Vector<T,N>& v1, const Vector<T,N>& v2 )
{
	T prod=0;
	for( size_t s=0; s<N; ++s )
		prod += v1[s]*v2[s];
	return prod;
}

int main()
{
	Vector<float, 3> v1 = { 1, 2, 3 };
	Vector<float, 3> v2 = { 3, 2, 1 };
	cout << dot_prod( v1, v2 ) << endl;

}
which will ensure that the two Vectors dot producted will always be the same size.

Another advantage of making your own vector class is that you can include things like normalisation and all the other useful vector operations.
 
Old 11-06-2003, 10:10 AM   #7
jim mcnamara
Member
 
Registered: May 2002
Posts: 964

Rep: Reputation: 36
Check out the concept of smart pointers, or consider the boost library

www.boost.org
 
Old 11-06-2003, 03:38 PM   #8
mr_segfault
Member
 
Registered: Oct 2003
Location: Australia
Distribution: Redhat 9
Posts: 95

Rep: Reputation: 15
dakensta,

Why did you choose float when it is storing ints?
 
Old 11-06-2003, 05:19 PM   #9
dakensta
Member
 
Registered: Jun 2003
Location: SEUK
Distribution: Debian & OS X
Posts: 194

Rep: Reputation: 35
Most vector calculations I use are float or double precision (and I would have thought in general too), so force of habit I guess - int's would be fine for a dot product but add in, say magnitude, and you really need better precision.


1, 2, 3 were just the first numbers to come into my head, the type has already been specified in the template parameter, so there is no ambiguity

While I am in the confession box, I used a struct in the example, rather than a class, out of habit too - slightly easier when selecting an example and cutting and pasting some code to quickly check and compile.

The example was really only to show the use of a template parameter as one possible method to include the size into a vector, where the size is not going to change. I added the type T to show maybe more familiar(?) template syntax for comparison and also allows int's to be used if that is what the original poster specifically requires. The operator[] was to keep the array-like syntax of arrays and std::vectors --- there are plenty of extensions that could be added (one useful one is cast to pointer, to substitute with functions that are defined like schatoor's dotProd)

Sorry for any confusion, point duly noted and I hope this clears things up.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
c++: array size limit? bigfatdud Programming 14 01-27-2005 11:19 AM
how to find out an array size on c++ poeta_boy Programming 9 06-22-2004 01:28 PM
Size of an array in C Hady Programming 6 04-06-2004 05:33 AM
PERL: Size of an array of an Array inspleak Programming 2 03-10-2004 02:24 PM
size of an array Longinus Programming 8 03-08-2004 01:48 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:11 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration