By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,534 Members | 1,811 Online
Bytes IT Community
+ Ask a Question
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

Nepomuk
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
  1. 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
  1. #include <iostream>
  2.  
  3. int length(int * array){return sizeof(array)/sizeof(array[0]);}
  4.  
  5. int main()
  6. {
  7.     int array1[4] = {3,2,1,0};
  8.     std::cout << "Length of array1: " << sizeof(array1)/sizeof(array1[0]) << "\n"
  9.         << "length(array1) = " << length(array1)
  10.         << endl;
  11. }
  12.  
The output is:
Expand|Select|Wrap|Line Numbers
  1. Length of array1: 4
  2. 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
Share this Question
Share on Google+
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

Nepomuk
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
  1. class Array<T>
  2. {
  3. private:
  4.     unsigned int length = 0;
  5.  
  6. public:
  7.     T myArray[];
  8.  
  9.     void setArray(int array*, unsigned int le)
  10.     {
  11.         myArray = array;
  12.         length = le;
  13.     }
  14.  
  15.     T* getArray()
  16.     {
  17.         return myArray;
  18.     }
  19.  
  20.     unsigned int getLength()
  21.     {
  22.         if(length==0) length = sizeof(array)/sizeof(array[0]);
  23.         return length;
  24.     }
  25. }
  26.  
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 <vector>.

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

Nepomuk
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

Nepomuk
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
  1. #define NULL 0
  2.  
  3. #include <stdio.h>
  4.  
  5. class IntArray
  6. {
  7.     private:
  8.  
  9.     protected:
  10.         //This stores the array
  11.         int* iArray;
  12.         //This stores the size of the array
  13.         int size;
  14.  
  15.     public:
  16.         IntArray();
  17.         IntArray(int);
  18.         IntArray(IntArray&);
  19.         void delArray(void);
  20.         int* getArray(void);
  21.         void initArray(int);
  22.         void setArray(int);
  23.         int sizeOf(void);
  24. };
  25.  
  26. //Sets the array to NULL if no argument is provided
  27. IntArray::IntArray(void)
  28. {
  29.     IntArray::iArray = NULL;
  30. }
  31.  
  32. //Sets the size and allocates memory for the array
  33. IntArray::IntArray(int size)
  34. {
  35.     IntArray::iArray = new int[size];
  36.     IntArray::size = size;
  37. }
  38.  
  39. //Copies an already existing IntArray
  40. IntArray::IntArray(IntArray &copy)
  41. {
  42.     int i;
  43.  
  44.     IntArray::size = copy.sizeOf();
  45.     IntArray::iArray = new int[IntArray::size];
  46.  
  47.     for(i = 0; i < IntArray::size; i++)
  48.     {
  49.         IntArray::iArray[i] = copy.getArray()[i];
  50.     }
  51. }
  52.  
  53. //Clears the arrays memory
  54. void IntArray::delArray(void)
  55. {
  56.     IntArray::iArray = NULL;
  57.     IntArray::size = 0;
  58. }
  59.  
  60. //Returns the array
  61. int* IntArray::getArray(void)
  62. {
  63.     return IntArray::iArray;
  64. }
  65.  
  66. //Initializes the array if it has not already been initialized
  67. void IntArray::initArray(int size)
  68. {
  69.     if(iArray == NULL)
  70.     {
  71.         IntArray::iArray = new int[size];
  72.         IntArray::size = size;
  73.     }
  74. }
  75.  
  76. //Deletes the existing array if it exists and re-initializes the array
  77. void IntArray::setArray(int size)
  78. {
  79.     if(iArray != NULL)
  80.     {
  81.         delete IntArray::iArray;
  82.         IntArray::iArray = NULL;
  83.     }
  84.  
  85.     IntArray::iArray = new int[size];
  86.     IntArray::size = size;
  87. }
  88.  
  89. //returns the size of the array
  90. int IntArray::sizeOf(void)
  91. {
  92.     return IntArray::size;
  93. }
  94.  
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
  1. #include "IntArray.h"
  2. #include <stdio.h>
  3.  
  4. #define BASE  0
  5. #define MULT  2
  6. #define TOP  10
  7. #define NEW  12
  8. #define NEWS 10
  9. #define NEWL 11
  10.  
  11. int main(void)
  12. {
  13.     int      i;
  14.     IntArray *myFirstArray;
  15.     IntArray *mySecondArray;
  16.  
  17.     //Creates an array of 10 ints
  18.     myFirstArray = new IntArray(10);
  19.  
  20.     //Sets each element equal to its element number times 2
  21.     for (i = BASE; i < TOP; i++)
  22.     {
  23.         myFirstArray->getArray()[i] = i * MULT;
  24.     }
  25.  
  26.     //Copies the first array
  27.     mySecondArray = new IntArray(*myFirstArray);
  28.  
  29.     //Multiplies each element of the second array by 2
  30.     for (i = BASE; i < TOP; i++)
  31.     {
  32.         mySecondArray->getArray()[i] = mySecondArray->getArray()[i] * MULT;
  33.     }
  34.  
  35.     //Outputs the sizes and values of each array
  36.     printf("\n\nSize Of");
  37.     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf());
  38.     printf("\n\nValues:");
  39.     printf("\n 1st     2nd");
  40.  
  41.     for (i = BASE; i < TOP; i++)
  42.     {
  43.         printf("\n%-4i    %-4i", myFirstArray->getArray()[i], mySecondArray->getArray()[i]);
  44.     }
  45.  
  46.     printf("\n\nReinitialize 2nd Array");
  47.  
  48.     //Reinitializes the second array
  49.     mySecondArray->setArray(NEW);
  50.  
  51.     //Sets new values for each element of the now 12 element second array
  52.     for (i = BASE; i < NEW; i++)
  53.     {
  54.         mySecondArray->getArray()[i] = i * i * MULT;
  55.     }
  56.  
  57.     //Outputs the sizes and values of each array
  58.     printf("\n\nSize Of");
  59.     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf());
  60.     printf("\n\nValues:");
  61.     printf("\n 1st     2nd");
  62.  
  63.     for (i = BASE; i < TOP; i++)
  64.     {
  65.         printf("\n%-4i    %-4i", myFirstArray->getArray()[i], mySecondArray->getArray()[i]);
  66.     }
  67.     printf("\n        %-4i", mySecondArray->getArray()[NEWS]);
  68.     printf("\n        %-4i", mySecondArray->getArray()[NEWL]);
  69.  
  70.     //Clears the first array
  71.     myFirstArray->delArray();
  72.  
  73.     //Outputs the sizes and values of each array
  74.     printf("\n\nSize Of");
  75.     printf("\n1st Array: %-2i    2nd Array: %-2i", myFirstArray->sizeOf(), mySecondArray->sizeOf());
  76. }
  77.  
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, <stdio.h> is deprecated in C++, use <cstdio> instead.
Jul 8 '08 #11

P: 60
Despite it being depricated, it is still in rather common use (<stdio.h> 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 <double>s, <int>s and <whathaveyou>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 <stdio.h>, 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. <stdio.h> 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 <stdio.h> rather than <cstdio>. 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. </lumbergh>
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<int> 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<int> 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<float> 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

Nepomuk
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

Banfa
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
  1. #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
  1. #include <stdio.h>
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
  1. 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
  1. IntArray *myFirstArray;
  2. IntArray *mySecondArray;
  3.  
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 (<stdio.h> 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 <double>s, <int>s and <whathaveyou>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

P: 60
#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.
That is a preference. Where I work, using defines is part of the code format standard, so it is what I use on a daily basis and that is what I am used to. Therefore it will show in what I code. Where I work, it is also not standard to use 0 as NULL for all procedures since some procedures use 0 for other things (I work with alot of legacy code).


#include <stdio.h>
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.
I've already stated that I see little problem with using stdio.h. I've conceded that it shouldn't be done, but again, I work with alot of legacy code, it's what I end up using alot, and it shows.

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.
I'm rather biased against generics as i've already stated. I feel they are quite ugly and are hard to read. They can also lead to code bloat.

Ctors/Dtors:
No exception safety in allocation. No freeing of memory (!) (there's no dtor).
I simply forgot a deconstructor (due to the aformentioned writing in 5 minutes). I accept this is a flaw.

Copying array values:
I would have used std::copy. Why reimplement this portion?
Again, a simple oversight on my part. I don't work much with arrays, prefering vectors myself (although sometimes it is unavoidable).

It directly sets the pointer to 0 (no freeing the memory!).
Oddly enough, in the code I have saved locally on my computer, I have 'delete IntArray::iArray;' in that class member function.

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.
I concede this point, but it was faster. Perhaps:
Expand|Select|Wrap|Line Numbers
  1. int IntArray::getElement(int element)
  2. {
  3.     return IntArray::iArray[element];
  4. }
  5.  
would have been better (still not perfect though).

Unnecessary setArray:
Unneeded because that's what a ctor is for.
setArray resizes the array. initArray is more like what you are talking about here. My reason for initArray was to allow a person to create a new null set through the default constructor and later initialize it to a non-null set.

Dubious naming of sizeOf.
Can be confused with compile time sizeof operator. Not like normal STL containers, which would implement size().
This is more of an opinion than a flaw. This could be easily fixed by just naming it numberOfElements, but that takes alot more typing... and don't suggest numElem. Is that elements? elementary? elementals? I don't like ambiguous abbreviations.

Missing critical operators:
Like say, the subscript operator?
This was not inteded to be a total solution, do not treat it as such. I even stated this before.

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.
Again, opinion. Defines are just fine. Some people don't like them others do. Some coding format standards for some companies require them others do not. There are good arguments for and against and I will do whatever the person who pays me says since it is irrelevant to doing my job.

Code: ( text )
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.
I *prefer* pointers to classes.


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.
All of which were written to this companies coding format specification (including the defines).

But more to the point, let's look at two examples:
Expand|Select|Wrap|Line Numbers
  1.     iostream << setprecision << 2 << setw << 4 << "    " << myFloat << setprecision << 2 << setw << 4 << myFloat;
  2.  
versus
Expand|Select|Wrap|Line Numbers
  1.     printf("%-4.2f    %-4.2f", myfloat, myfloat);
  2.  
I'll take the second, thank you.


Despite it being depricated, it is still in rather common use (<stdio.h> 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?
See above.

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 <double>s, <int>s and <whathaveyou>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?
As I stated before, if I were to really spend time developing this idea, I would first start by creating a Number class that was inherited by Integer, Float, Double, et cetera classes. I would then create an NumberArray Class that would be inherited by the IntegerArray, FloatArray, et cetera classes. I would then put the primary (read as repeating functionality) in the top level class (NumberArray). While this requires a little more code on the front end, it is not a significant amount. This also comes with the advantage that an IntegerArray could be quickly and easily turned into a LongArray using Polymorphism. But this, again, is a preference. I don't work with arrays enough to warrant that because we use vectors unless completely unavoiable here at The City.

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.
I know how to handle templates. They are actually quite useful in some circumstances, but I do beleive they are entirely overused. And no amount of argueing will convince me that aren't ugly in the context of C++. Angled brackets belong in HTML, not C++.

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 little bloat on the backend versus a little on the front end. Doesn't sound much different to me.

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.
I believe I've responded to all your assertations. Take it for what you will.

As for the analogy, I could say that it takes the same amount of time to say the Earth is round (5 seconds). However, to really be able to prove that would take alot of work on someones part. So we resolve to saying that the "Earth is Round" all the time, despite the fact that it is technically wrong. It is 'good enough' to say it. But in reality, roundness is a 2-dimentional quality. The Earth is actually spherical. Even that, though, is only technically 'good enough' to get the point accross. To really state such would require to say that the Earth is an 3-dimentional Ellipsoid with an irregular surface. When I'm talking to someone, though, I'd rather just say the Earth is round, and they will know what I mean.

Here I threw something together really quickly to illustrate a point. It wasn't intended to be perfect or complete, but it is far better than you give it credit for. I've already acknowledged where I think there are actual flaws. Take it or leave it.

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. Quote:
Originally Posted by
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?
Not even remotely, provided you understand what I said earlier about an object heirarchy. Personally I've been toying with the idea of creating type wrapper classes for C++ for a while and this would just be an extention. I prefer working with objects in total to basic data types (and yes I understand that they will still be basic data types on the backend, but so are all objects, and I prefer working with the objects directly and data types indirectly).

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.
This was in reference to the attitude you took originally. It is indeed irrelevant to whether the code is good, but as stated above, I believe I've addressed all your concerns and that you were far overreacting to much opinion and a few actual minor flaws.

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++.
Correct. C++ is indeed not C. It is C with classes:-p

I concede I shouldn't have used <stdio.h>. I also concede this code is not perfect. However, it is workable and gives an idea of what could be done to the questioner. I also think you like generics a bit too much. Most of your issue with my code was that I didn't use a generic class. Just remember, a tool for every job and a job for every tool. This didn't require it nor justify it.

I do appreciate you taking the time to actually make your points. The initial attitude was abbrasive to say the least, but these two posts were much better at addressing the actual issues you had and not attacking the person.
Jul 9 '08 #26

100+
P: 110
why don't you do

Expand|Select|Wrap|Line Numbers
  1. sizeof(array) / sizeof (arrayType)
Jul 9 '08 #27

100+
P: 424
why don't you do
Expand|Select|Wrap|Line Numbers
  1. sizeof(array) / sizeof (arrayType)
sizeof (arrayType) will give the size of a pointer which is 4 bytes on a 32bit machine or 8 on a 64bit machine, regardless of what type the array contains.
Jul 10 '08 #28

Nepomuk
Expert 2.5K+
P: 3,112
why don't you do

Expand|Select|Wrap|Line Numbers
  1. sizeof(array) / sizeof (arrayType)
In the original question, I explain, that this doesn't work and I'm looking for an alternative. arnaudk explained the reason. But thank you for trying to help.

Greetings,
Nepomuk
Jul 10 '08 #29

Post your reply

Sign in to post your reply or Sign up for a free account.