425,534 Members | 1,811 Online
Need help? Post your question and get tips & solutions from a community of 425,534 IT Pros & Developers. It's quick & easy.

Calculating the size of an array

 Expert 2.5K+ P: 3,112 Hi! I've read, that in C++ there's no predefined method, to calculate the size of an array. However, it's supposed to work with Expand|Select|Wrap|Line Numbers sizeof(array)/sizeof(array[0]) Now, this does work in some situations, but not in others. Here's what I mean: Expand|Select|Wrap|Line Numbers #include    int length(int * array){return sizeof(array)/sizeof(array[0]);}   int main() {     int array1[4] = {3,2,1,0};     std::cout << "Length of array1: " << sizeof(array1)/sizeof(array1[0]) << "\n"         << "length(array1) = " << length(array1)         << endl; }   The output is: Expand|Select|Wrap|Line Numbers Length of array1: 4 length(array1) = 1 Now, I'm guessing, that my function length is just checking the size of the pointer to the first element of the array. My question is: Is there any method, to determine the size of an array, after this has been passed to a function? I'd hate to have to pass on that kind of information as an argument to every function, that needs the size of the array, manually. Greetings, Nepomuk Jul 7 '08 #1
28 Replies

 Expert 100+ P: 671 I'd hate to have to pass on that kind of information as an argument to every function, that needs the size of the array, manually. Sorry. Pass the information. Ever see C stdlib functions like strncpy? Guess why they ask you to manually tell them the size of the array. Jul 7 '08 #2

 100+ P: 424 You could use some terminating element in your array, then your length function count the number of elements until the terminating element. C strings are character arrays that are null terminated in this manner. Jul 8 '08 #3

 Expert 2.5K+ P: 3,112 Sorry. Pass the information. Ever see C stdlib functions like strncpy? Guess why they ask you to manually tell them the size of the array. Grrr... Why can't C++ be a bit more like Java in that way... :-( You could use some terminating element in your array, then your length function count the number of elements until the terminating element. C strings are character arrays that are null terminated in this manner. That's a bit difficult, if it's an array of integers, because that would mean, that I can't use some specific numbers. But how about something like this: Expand|Select|Wrap|Line Numbers class Array { private:     unsigned int length = 0;   public:     T myArray[];       void setArray(int array*, unsigned int le)     {         myArray = array;         length = le;     }       T* getArray()     {         return myArray;     }       unsigned int getLength()     {         if(length==0) length = sizeof(array)/sizeof(array[0]);         return length;     } }   There are probably errors in that code, but the idea should be clear: It would allow you to set an array directly (as it is public) or use the setArray method, giving the length. Of course, methods to access the elements would be needed to. I would guess, that I'm not the first person to have this idea and there's probably something like that in std - does anyone know of such a class? Greetings, Nepomuk Jul 8 '08 #4

 Expert 100+ P: 849 The class you're looking for is the std::vector, defined for your convenience in . C/C++ arrays don't do bounds checking for overhead reasons, as doing so increases the time for every array access a fair bit. Thus, they expect the programmer to handle these things for himself. It can be annoying, but there you have it. Jul 8 '08 #5

 Expert 2.5K+ P: 3,112 OK, thank you - I'll try using vectors. I knew about them (well, tried using them a while ago), but I thought, they were just dynamic arrays and never thought about using them that way. Well, you live and learn! :-) Greetings, Nepomuk Jul 8 '08 #6

 Expert 100+ P: 671 Use either Boost.Array (fixed sized) or std::vector (dynamic size) Jul 8 '08 #7

 Expert 2.5K+ P: 3,112 Use either Boost.Array (fixed sized) or std::vector (dynamic size) Thanks, the Boost.Array looks just right! But I might still use the vector. We'll see... Greetings, Nepomuk Jul 8 '08 #8

 Expert 10K+ P: 11,448 Thanks, the Boost.Array looks just right! But I might still use the vector. We'll see... Greetings, Nepomuk Consider the Boost arrays equivalent to Java's arrays; the vector is more like an ArrayList in Java. kind regards, Jos Jul 8 '08 #9

 P: 60 You could use vectors or you could just create a class to wrap the type of array you want. For instance, for an integer array you could use: IntArray.h Expand|Select|Wrap|Line Numbers #define NULL 0   #include    class IntArray {     private:       protected:         //This stores the array         int* iArray;         //This stores the size of the array         int size;       public:         IntArray();         IntArray(int);         IntArray(IntArray&);         void delArray(void);         int* getArray(void);         void initArray(int);         void setArray(int);         int sizeOf(void); };   //Sets the array to NULL if no argument is provided IntArray::IntArray(void) {     IntArray::iArray = NULL; }   //Sets the size and allocates memory for the array IntArray::IntArray(int size) {     IntArray::iArray = new int[size];     IntArray::size = size; }   //Copies an already existing IntArray IntArray::IntArray(IntArray ©) {     int i;       IntArray::size = copy.sizeOf();     IntArray::iArray = new int[IntArray::size];       for(i = 0; i < IntArray::size; i++)     {         IntArray::iArray[i] = copy.getArray()[i];     } }   //Clears the arrays memory void IntArray::delArray(void) {     IntArray::iArray = NULL;     IntArray::size = 0; }   //Returns the array int* IntArray::getArray(void) {     return IntArray::iArray; }   //Initializes the array if it has not already been initialized void IntArray::initArray(int size) {     if(iArray == NULL)     {         IntArray::iArray = new int[size];         IntArray::size = size;     } }   //Deletes the existing array if it exists and re-initializes the array void IntArray::setArray(int size) {     if(iArray != NULL)     {         delete IntArray::iArray;         IntArray::iArray = NULL;     }       IntArray::iArray = new int[size];     IntArray::size = size; }   //returns the size of the array int IntArray::sizeOf(void) {     return IntArray::size; }   For a float array, simply change the apropriate ints to floats in the class. Here is an example of it in use: Test.cpp Expand|Select|Wrap|Line Numbers #include "IntArray.h" #include    #define BASE  0 #define MULT  2 #define TOP  10 #define NEW  12 #define NEWS 10 #define NEWL 11   int main(void) {     int      i;     IntArray *myFirstArray;     IntArray *mySecondArray;       //Creates an array of 10 ints     myFirstArray = new IntArray(10);       //Sets each element equal to its element number times 2     for (i = BASE; i < TOP; i++)     {         myFirstArray->getArray()[i] = i * MULT;     }       //Copies the first array     mySecondArray = new IntArray(*myFirstArray);       //Multiplies each element of the second array by 2     for (i = BASE; i < TOP; i++)     {         mySecondArray->getArray()[i] = mySecondArray->getArray()[i] * MULT;     }       //Outputs the sizes and values of each array     printf("\n\nSize Of");     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf());     printf("\n\nValues:");     printf("\n 1st     2nd");       for (i = BASE; i < TOP; i++)     {         printf("\n%-4i    %-4i", myFirstArray->getArray()[i], mySecondArray->getArray()[i]);     }       printf("\n\nReinitialize 2nd Array");       //Reinitializes the second array     mySecondArray->setArray(NEW);       //Sets new values for each element of the now 12 element second array     for (i = BASE; i < NEW; i++)     {         mySecondArray->getArray()[i] = i * i * MULT;     }       //Outputs the sizes and values of each array     printf("\n\nSize Of");     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf());     printf("\n\nValues:");     printf("\n 1st     2nd");       for (i = BASE; i < TOP; i++)     {         printf("\n%-4i    %-4i", myFirstArray->getArray()[i], mySecondArray->getArray()[i]);     }     printf("\n        %-4i", mySecondArray->getArray()[NEWS]);     printf("\n        %-4i", mySecondArray->getArray()[NEWL]);       //Clears the first array     myFirstArray->delArray();       //Outputs the sizes and values of each array     printf("\n\nSize Of");     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf()); }   BTW, arrays in Java were implimented as a class similarly to this, only in Java it is pre-written for you. Jul 8 '08 #10

 Expert 100+ P: 849 Or, as the OP suggested in an earlier post, you could use templates so that you don't need eighteen different versions of nearly identical classes. Also, is deprecated in C++, use instead. Jul 8 '08 #11

 P: 60 Despite it being depricated, it is still in rather common use ( that is). And as for templates, bleh. It makes all the code ugly with all those damned angled brackets and even longer names. You save time on the front end by not copying and pasting the code a few times for each type, but then you lose it on the backend having to type all those damn s, s and s on the backend everytime you use it your template. Plus, in regards to templates, a float and int are not always going to have the same member functions, so it would probably, in all honesty, be best to impliment it as a inherited heirarchy (IntArray, FloatArray, DoubleArray, et cetera, inherit NumberArray which, if you really have alot of time, could inherit ObjectArray or such). That would probably be the best idea. Jul 8 '08 #12

 Expert 100+ P: 671 fauxanadu, I was going to say "That's a funny joke". Then I actually looked at the code you wrote above, and came to two conclusions. You are either making a very elaborate bad joke, or you an utterly horrible C programmer who started picking up C++ syntax without learning how to actually use C++. If you fall into the unfortunate latter case, the best thing you can do is to temporarily drop C and C++, and pick a very high level language to work with. At that point, poor programming practices will stick out very sorely, and you'll be forced to correct yourself. At which point you may then consider returning to C++. Jul 8 '08 #13

 P: 60 A) That code was written in about 5 minutes. Do better in less then we'll talk about structure. (You did mean structure, right? Because there is nothing wrong with the syntax.) B) Each person has their coding preference. Mine is against templates. They are, to say the least, ugly and make the code far more difficult to read. There are many paths to produce the same result. C) My job description requires that I produce solutions for my employer in VB, Java, C++, and Assembly depending on the situation. (I'll simplify this point for you: I program in high level, high-ish leveled, medium leveled, and low-leveled languages). My reviews are always positive and I have nothing but praise from the higher ups about my results. So as you can see, your point is both flawed and meaningless. D) As it stands, I gave a solution to the above stated problem, someone stated an opinion about my code, I responded with my opinion, and then you began with ad hominen attacks. If you have such a problem with the code listing above, feel free to point out the actual problems you feel are there. If you have an opinion, try defending it with actual arguments. E) In regards to , regardless of whether it is depricated or not, it is still in wide use. Not only is it in wide use, but C++, by design, retains all of C in its specification. is not depricated in C and as such will not be going away soon nor is it bad practice within C to use it. I might add I only added it to quickly output an example. The class itself has nothing to do with it and as such it is meaningless as to whether it is depricated or not. Jul 8 '08 #14

 Expert 100+ P: 849 The deprecated part is using it as rather than . That's been deprecated for about 10 years now. However, all this is more than a little off topic for this thread. How about we all just calm down a little, mmkay? I'll need you guys to come in on Saturday too, mmkay. Jul 8 '08 #15

 P: 60 I'm not aggitated at what you said Laharl. It was a good point (and a good name to boot. Disgaea is a wonderful game!). I just responded that I don't like templates (it is a personal preference). I am aggitated at the fact that this other person comes along and starts in with the attacks against my character acting like I don't know jack about programming. Especially when i'm merely attempting to be helpful. Jul 8 '08 #16

 Expert 100+ P: 671 You need a thicker skin. To the OP's technical question, you proposed solutions that not only would be bad, but defended them with technically unacceptable arguments. When I get the chance, I'll go through your code completely, explain its flaws, and post them in a new thread. EDIT: To be precise, I actually thought you were making an elaborate joke. Based on your next two responses, it seems like you were actually serious... Jul 8 '08 #17

 P: 12 You are absolutely right fauxanadu, this code here: std::vector MyArray; is uglier than the 200 lines of code you wrote. What I suggest you do, to help ease the pain, is this: typdef std::vector IntArray; IntArray MyArray; Although we doubled our initial code, which is barely acceptable, we are still under your 200 lines, which might, in the end be forgivable, when we do the float version of your class and ours.... Let me try: typdef std::vector FloatArray; FloatArray MyOtherArray; Woah, I'm exhausted. Jul 8 '08 #18

 Expert 10K+ P: 11,448 C) [ ... ] My reviews are always positive and I have nothing but praise from the higher ups about my results. So as you can see, your point is both flawed and meaningless. This subject certainly doesn't need a heated debate and most certainly not a non sequitur like this; as everybody knows (or should know) templates can cause code bloat as oler1s pointed out, just as your way of working; nothing personal here and nothing to get agitated about. Please keep this discussion a nice and technical one, not a personal one; for references read Weinberg's "egoless programming". Let the show continue ;-) kind regards, Jos (moderator) Jul 8 '08 #19

 Expert 2.5K+ P: 3,112 Woah, I hadn't expected anything like this, when I asked the question! Now, I'd like to say "Thank you!" to everybody, who took the time to go through the thread and to, eventually, find the best (or should I say "a best") solution to my request. Sometimes, it is overwhelming, how much thought and feelings people put into solving a problem. @oler1s: Thank you for trying to prevent me from doing anything utterly wrong, even if your comments were not in line with everyone's opinion. @arnaudk: Thank you again for your suggestion. As I said before, it's not an option for me, but certainly something to hold in mind for later occasions. @Laharl: Although you made suggestions towards the solution, I guess your main input to this Thread was: "Calm down!" ^^ Thanks for that and for your suggestions. @JosAH: OK, your reply #9 certainly helps me to understand the differences between C/C++ and Java. @fauxanadu: I haven't looked at your solution very much yet, but I certainly will - even if it should be badly structured (which I wouldn't be able to tell until I've had a good look at it), I'm sure, there's a lot I can learn from it. @Sirmont: Hm, that's an interesting idea. I'll think about that. It can certainly save a lot of typing at times. Now, I haven't used any of the solutions yet in the overall problem I'm trying to solve, but I guess I'll check a few out and then decide, which I like best for this task. Greetings, Nepomuk Jul 8 '08 #20

 Expert Mod 5K+ P: 8,916 ... the best (or should I say "a best") solution I think the term you are looking for is "a solution" :D The term best is not required, it almost certainly breaks Joshs egoless programming paradigm and if you are going to say best then you are going to have to defined how you are judging best because the best solution will be dependent on circumstance. For instance the best solution to a given problem will be different given 1 week and infinite cash to the solution to the same problem given infinite time but only £100. Something I heard a year or so ago which I like was, for a given programming task the solution can have the following qualities (assuming that the solution is working correctly) It's Cheap It's Well Written It's Produced Quickly But it can only have 2 of those 3 qualities. Jul 8 '08 #21

 Expert 10K+ P: 11,448 Something I heard a year or so ago which I like was, for a given programming task the solution can have the following qualities (assuming that the solution is working correctly) It's Cheap It's Well Written It's Produced Quickly But it can only have 2 of those 3 qualities. Nice one! IMHO most of the software has only one or less of those qualities ;-) kind regards, Jos Jul 9 '08 #22

 Expert 100+ P: 671 If anyone (including Fauxanadu) wants to discuss something in private in relation to my posts in this thread, do PM me. Fauxanadu, I honestly thought you were either trolling or making a bad joke, so I realize you are severely offended when taking some of my remarks in earnest. However, my professional and technical criticism of your code, and programming statements, still remain. I expand on it here. I'll begin my criticizing the code first. From top to bottom: In IntArray.h: Expand|Select|Wrap|Line Numbers #define NULL 0 Not necessary in C++. Just use 0 in it's place. Since it's preferable not to have defines, I consider using a define for NULL bad programming practice. Expand|Select|Wrap|Line Numbers #include  Deprecated in C++. Whatever your argument about deprecation, there's a big, big reason you don't want to do this in a header file. stdio.h works by bringing in cstdio, then including the entire namespace std. Since a using namespace std; in a header file is a definite no-no, this makes including stdio.h completely unacceptable. Expand|Select|Wrap|Line Numbers class IntArray Here, you have directly coupled the idea of an array to the int datatype. C++ has facilities to decouple the implementations, as the Boost.Array container has done. Therefore, your implementation already has a big black mark against it. What we want is a first class array object, that has type safety, as little overhead over a normal array, plays well with STL and general usage, and is highly reusable. Tight coupling is a huge strike, as you have not created a generic and reusable array type. Ctors/Dtors: No exception safety in allocation. No freeing of memory (!) (there's no dtor). Copying array values: I would have used std::copy. Why reimplement this portion? delArray is bad: It directly sets the pointer to 0 (no freeing the memory!). Dubious implementation of getArray: The point of your array object is to not have the programmer deal with a raw array. You want to wrap around this array and present a proper interface, not wrap and then give a bunch of set and get functions. You've done nothing but write bloat. Unnecessary setArray: Unneeded because that's what a ctor is for. Dubious naming of sizeOf. Can be confused with compile time sizeof operator. Not like normal STL containers, which would implement size(). Missing critical operators: Like say, the subscript operator? For Test.cpp Use of defines instead of constant ints is C-ish code. You want to create actual constants, which are typesafe and dealt with the compiler, not the pre-compiler. Expand|Select|Wrap|Line Numbers IntArray *myFirstArray; IntArray *mySecondArray;   Dubious usage. One of the ideas behind a first class type is that the programmer doesn't have to deal with pointers that needs to be managed. Usage of printf in C++. Why don't you use iostreams? Definitely more typesafe than the variadic printf. Actually, that code is confusing because of cryptic usage of BASE, MULT, TOP, NEW, NEWS(!), and NEWL(!) macros. Finally, this code implements no interface that works well with STL. No iterators. No common functions implemented by the other STL containers. That means I can't use std::copy or the like with your array type. All around, an unusable container. Jul 9 '08 #23

 Expert 100+ P: 671 Here, I criticize the rest of what Fauxanadu has said. It's all technical appraisal, so I hope this isn't taken as a ad hominem attack. Despite it being depricated, it is still in rather common use ( that is). It's in common use because of legacy code. Not because it is OK to keep using stdio.h on fresh codebases. And as for templates, bleh. It makes all the code ugly with all those damned angled brackets and even longer names. I don't believe so, but how is the aesthetic appeal of templates relevant? You save time on the front end by not copying and pasting the code a few times for each type, but then you lose it on the backend having to type all those damn s, s and s on the backend everytime you use it your template. You save a lot more when you use generics. Copy pasting code is bad because you exponentially increase maintainability. It increases the work you have to do. It bloats your codebase, because you have repeated yourself. Why are you, a programmer, doing repetitive work, when the computer should be doing it? Plus, in regards to templates, a float and int are not always going to have the same member functions, so it would probably, in all honesty, be best to impliment it as a inherited heirarchy Yet, the concept of an array is independent of the type. You don't want them to be coupled, providing interfaces instead for various operations. Besides, templates give you enormous flexibility in that you can have multiple orthogonal object policies resolved at compile time. Read Alexandrescu's "Modern C++" to see how he handles templates. In your code, you suggest replacing all instances of int with float to get an array type that works with float. Does that not suggest that the member functions for this array type are independent of the type? Furthermore, creating object hierarchies is bad for two major reasons. The first is that you automatically introduce performance penalties unnecessarily. Hierarchies need to be resolved at runtime. Furthermore, it requires coupling. Everytime you want an array of a new type, you repeat code, inherit from some common base, and so on. You created a bloated object hierarchy, all of which involve repeated code. Does this sound appealing to you? A) That code was written in about 5 minutes. I could take 5 seconds to say "The Earth is flat." I could also take 1 year to form that statement. Regardless of how long, my statement is wrong. That you took under 5 minutes to write up the code is irrelevant. It's broken and unusable. If you don't want to be criticized for bad code, and don't want to come off as a bad coder, take the time to write proper code. This is a technical forum, and technical accuracy is valued. Each person has their coding preference. Mine is against templates. One does not have preferences in programming like one prefers colors, or ice cream. A programmer needs to make choices based on technical reasons. They are, to say the least, ugly and make the code far more difficult to read. There are many paths to produce the same result. There must be many paths to produce the same result. Because you have a generic container (multiple of one type) applied to infinitely many types. Your idea has programmers manually copying code (and thus code paths) for each type. Using a template has the computer do it. Is not your idea uglier, more difficult to read, far more difficult to maintain? My job description... Is irrelevant. Obviously, the reputation and knowledge of people carries weight in the argument. But it does not make it correct. Furthermore, do not expect that in a technical discussion, you will be shielded by reputation, past work, or titles. Not only is it in wide use, but C++, by design, retains all of C in its specification. No. C++ is not C. it is not C with a few things tacked on. It is a different language, that implements a subset of C. Therefore, there is very good compatibility with C code. However, it is not complete, and furthermore, idiomatic C code and C++ code differ. If you program C code with a C++ compiler, that's up to you. But it's not idiomatic C++. Jul 9 '08 #24

 Expert 10K+ P: 11,448 Just to be sure I post the following text verbatim here; just so that this thread doesn't go out of hand. kind regards, Jos -------------------------------------------------------------------------------- The following text is not mine; it's a summary of Henry Weinberg's essay on egoless programming; read it and realize how true it all is. The Ten Commandments 1) Understand and accept that you will make mistakes. The point is to find them early, before they make it into production. Fortunately, except for the few of us developing rocket guidance software at JPL, mistakes are rarely fatal in our industry, so we can, and should, learn, laugh, and move on. 2) You are not your code. Remember that the entire point of a review is to find problems, and problems will be found. Don't take it personally when one is uncovered. 3) No matter how much "karate" you know, someone else will always know more. Such an individual can teach you some new moves if you ask. Seek and accept input from others, especially when you think it's not needed. 4) Don't rewrite code without consultation. There's a fine line between "fixing code" and "rewriting code." Know the difference, and pursue stylistic changes within the framework of a code review, not as a lone enforcer. 5) Treat people who know less than you with respect, deference, and patience. Nontechnical people who deal with developers on a regular basis almost universally hold the opinion that we are prima donnas at best and crybabies at worst. Don't reinforce this stereotype with anger and impatience. 6) The only constant in the world is change. Be open to it and accept it with a smile. Look at each change to your requirements, platform, or tool as a new challenge, not as some serious inconvenience to be fought. 7) The only true authority stems from knowledge, not from position. Knowledge engenders authority, and authority engenders respect—so if you want respect in an egoless environment, cultivate knowledge. 8) Fight for what you believe, but gracefully accept defeat. Understand that sometimes your ideas will be overruled. Even if you do turn out to be right, don't take revenge or say, "I told you so" more than a few times at most, and don't make your dearly departed idea a martyr or rallying cry. 9) Don't be "the guy in the room." Don't be the guy coding in the dark office emerging only to buy cola. The guy in the room is out of touch, out of sight, and out of control and has no place in an open, collaborative environment. 10) Critique code instead of people—be kind to the coder, not to the code.As much as possible, make all of your comments positive and oriented to improving the code. Relate comments to local standards, program specs, increased performance, etc. -------------------------------------------------------------------------------- Jul 9 '08 #25