954,504 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

get length of a dynamic array

Can't seem to figure this out.

string *array;
 
void addNodes(string names[])
{
	array = names;
	//how many elements in the array???
}
Phaelax
Practically a Posting Shark
858 posts since Mar 2004
Reputation Points: 92
Solved Threads: 51
 

>Can't seem to figure this out.
You're not the only one. There isn't a portable way to get the size of a dynamically allocated array. You need to pass the size to your function:

void addNodes(string names[], size_t size)
Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

[humor]
keep accessing array elements from 0 until the program segfaults, then back up one and that's your limit.
[/humor]

Chainsaw
Posting Pro in Training
436 posts since Jun 2004
Reputation Points: 36
Solved Threads: 11
 

I guess this would be helpful,
/******for a static array********/
char inp[4];
for (n=0;inp[n];n++)
; //do nothing inside the loop
cout<

swets_here
Newbie Poster
4 posts since May 2005
Reputation Points: 10
Solved Threads: 0
 

>> I guess this would be helpful
No, not a bit. Your code is wrong.

>> for (n=0;inp[n];n++)
Assuming that n was defined somewhere, the test for imp[n] against 0 is dngerous because imp is uninitialized. There could be a null character straight away, or 5000 characters later. You're really risking an access violation with this loop.

>> char *arr = new char [sizeof(char)];
This alloctes memory for one char. sizeof(char) is guaranteed to return 1, everywhere, without fail. That's one of the few absolutes when it comes to type sizes in C++.

>> for (n=0;arr[n];n++)
You have the same problem here as the previous loop.

Yes, your idea is valid assuming there's some sentinel value at the end of the array to stop the loop on. With the original question that's difficult because any string object is valid in the general case. That's probably why you took it upon yourself to change the example to char so that you could use a null character as the sentinel.

The best solution is to avoid using arrays in the first place because they're unsafe and most people don't understand them well enough to avoid the pitfalls, as displayed by your flawed example. The std::vector class provides a good container that grows dynamically.

Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

The easiest way to get the length of a dynamic array is this

sizeof(array)/sizeof(arraytype)

where array is your dynamic array and arraytype is the data type (for instance int)

Hope this helps :)

Becuzz
Newbie Poster
2 posts since Jun 2005
Reputation Points: 9
Solved Threads: 0
 

>> The easiest way to get the length of a dynamic array is this
Is it? Forget about the 'array' part and look closely at the 'dynamic' part. A dynamic array is not an array, it's a pointer to a block of memory that can be subscripted like an array:

#include <iostream>

#define length(x) (sizeof(x) / sizeof(*(x)))

void foo(int a[])
{
  std::cout << "From foo(): " << length(a) << '\n';
}

int main()
{
  int *a = new int[10];
  int b[10];

  std::cout << "From main(): " << length(a) << '\n';
  foo(b);
}

So the sizeof trick just breaks silently when you use it on a dynamic array, or an array passed as a function parameter. Templates are a better solution because they complain when you pass a pointer and not an array:

#include <iostream>

template <typename T, int sz>
char (&array(T(&)[sz]))[sz];

void foo(int a[])
{
  std::cout << "From foo(): " << sizeof array(a) << '\n';
}

int main()
{
  int *a = new int[10];
  int b[10];

  std::cout << "From main(): " << sizeof array(a) << '\n';
  foo(b);
}

The rule of thumb is that if you want the size of a dynamic array, you save it! If you want the size of an array parameter, you pass it! Anyone who doesn't know these rules or isn't comfortable with them would be better off using a smart container like std::vector or boost::array.

Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

Ok so i mistyped. Just make it this and it will work (i think)
sizeof(*names)/sizeof(string)

Happy?

P.S. btw i know to pass the length of a dynamic array or to use vector but im just trying to solve this guy's problem. (so stop criticizing people)

Becuzz
Newbie Poster
2 posts since Jun 2005
Reputation Points: 9
Solved Threads: 0
 

Try it with a dynamic array and find out you are wrong.

You are being helpfully corrected, you are the one starting to get out of line.

Dave Sinkula
long time no c
Team Colleague
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
 

I get 4 for the sizeof(string), hmmm?
I 'd say vectorize!

vegaseat
DaniWeb's Hypocrite
Moderator
5,989 posts since Oct 2004
Reputation Points: 1,345
Solved Threads: 1,417
 

>> Just make it this and it will work (i think)
No offense, but when you're guessing, you're not helping. Most of the time a guess is either grievously wrong, or has subtle problems.

>> so stop criticizing people
It's called constructive criticism. If you don't want to learn then don't bother trying to help because you'll just give bad advice. If you think you know everything then don't bother trying to help because you'll probably give bad advice and then turn the thread into a flame war when someone who knows better corrects you.

Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

I tried using the sizeof operator as suggested above. But everytime for an int array it gives "1" as output and for a char array it gives "4". No matter how many elements I store in the array.
I donot know the usage of std::vector or boost::array. Can someone help? Pls tell me how can I get the number of elements stored in a dynamic array using them?

P.S:I had changed the example to char type as I was not sure if 'String' is a valid data type in C or C++. Is it?

swets_here
Newbie Poster
4 posts since May 2005
Reputation Points: 10
Solved Threads: 0
 

Basically, the only way to do this is what narue suggested and pass in the actual size as a parameter to the function. Either that, or use an STL collection, and use .size()

winbatch
Posting Pro in Training
466 posts since Feb 2005
Reputation Points: 68
Solved Threads: 18
 

>> I tried using the sizeof operator as suggested above.
Don't bother, it won't work.

>> Pls tell me how can I get the number of elements stored in a dynamic array using them?
The only way to get the size of a dynamic array is to save the size when you allocate memory. The only way to get the size of an array parameter is to pass the size as another parameter:

// Get the size of a dynamic array
char *p = new char[10];
int sz = 10; // Save the size!
// Get the size of an array parameter
void foo(char array[], int size); // Pass the size!

>> I donot know the usage of std::vector or boost::array.
That's not a good excuse. ;) If you don't know the usage of a feature but you clearly need it, then it's time to learn. It's almost always better to use a container class than it is to use arrays anyway. Arrays are error prone while container classes work hard to protect you from those potential errors.

>> Is it?
String is not, unless you define it yourself, std::string is a class in the standard library.

Dogtree
Posting Whiz in Training
233 posts since May 2005
Reputation Points: 35
Solved Threads: 3
 

hi,

i'm studing computer sciences and i just met this problem.
i know it's been a long time the thread has been opened but i have one more question about it.

i already thought of passing the size of the dynamic array in parameter and i'm sure this will work fine, but as i am a studient, i always want to know more about it and even more when something seems wiered to me : if the only way of knowing the size of a dynamic array is by sending its size, how does free works ? you just pass the pointer as parameter and it cleans up the memory... i bet this function has the solution we are looking for.. but unfortunatly i have no books detailed enough to answer my question and i can't find anything on the web neither...

maybe there is a "Mister know-it-all" over here who can help me to understand that.

(i'm sorry if my english isn't verry correct but this is not my first language ;) and so, please don't make answers to hard to understand, thank you :D)

vamp74100
Newbie Poster
1 post since Dec 2006
Reputation Points: 10
Solved Threads: 0
 

Can't seem to figure this out.

string *array;
 
void addNodes(string names[])
{
	array = names;
	//how many elements in the array???
}

std::string has a functionsize() that will tell the current size.

void addNodes(string names[])
{
	cout << "size of array is " << names.size() << "\n";
}

>> array = names;
That does not work because you variablenames is a c++ class, not a pointer. If you want the pointer, then use c_str()

const char* array = names.c_str();
Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

std::string has a function size() that will tell the current size.

void addNodes(string names[])
{
    cout << "size of array is " << names.size() << "\n";
}


Hmm...you are forgetting thatnames is an array of strings and not a std::string or a vector. So you can't apply the size( ) function to it, it is applicable to C++ containers, not array of containers. The only way to do this thing correctly is to do it like specified by Miss Narue in the second post.

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 
Hmm...you are forgetting that names is an array of strings and not a std::string or a vector. So you can't apply the size( ) function to it, it is applicable to C++ containers, not array of containers. The only way to do this thing correctly is to do it like specified by Miss Narue in the second post.

Yes you are correct -- my mistake. Best thing for the op to do is use a vector instead of an array. I was wondering at the time how Narue could possibly make such a mistake -- turns out she didn't.

Ancient Dragon
Retired & Loving It
Team Colleague
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
 

I'm not an expert, but I was reading this article:
http://www.icce.rug.nl/docs/cplusplus/cplusplus09.html#l153

Apparently, if you overloaded the operator delete like this:
void operator delete[](void *p, size_t size);

the parameter "size" will tell you how long the array is.

However, if you want the normal delete[], you'll have to write "::delete[]"

s0me1
Newbie Poster
3 posts since Sep 2008
Reputation Points: 10
Solved Threads: 0
 

I'm not an expert, but I was reading this article: http://www.icce.rug.nl/docs/cplusplus/cplusplus09.html#l153

Apparently, if you overloaded the operator delete like this: void operator delete[](void *p, size_t size);

the parameter "size" will tell you how long the array is.

However, if you want the normal delete[], you'll have to write "::delete[]"


Curiously, the C++ standard does not actually specify what value is passed as the size_t argument. In practice, it would be reasonable to expect (hope?) it would have the value passed to the corresponding invocation of operator new[](). If so, it would have to be divided by sizeof(the_type) to get the number of elements.

Since the destructors of all elements of the array will have been invoked before operator delete[]() is actually called, there is not much that can be done with the size_t argument other than pass it to a deallocation function (eg ::operator delete[]()) or print out the number of elements that were in the array being deallocated. The elements themselves will no longer exist, so no operation on them is allowed.

grumpier
Posting Whiz in Training
211 posts since Aug 2008
Reputation Points: 193
Solved Threads: 32
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You