Refer to object without name (with array reference)...is this valid?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
That declares an array whose size is not known until run time.
I'm not certain what the C++ standard says about that. But I think it says you can't do that.
When I've tried that, it has worked. I think it may be an extension to the language generally supported by compilers.
Quote:
Foo theArray[i] = new Foo;
That is quite a bit less plausible.
It declares another array of the same name (that is not a problem because it is in an inner scope).
It obviously was intended to refer to an element of the first declaration, so the code is certainly wrong.
I've never tested the variable length local array feature inside a loop where the compiler would be unable to trivially manage the stack trick for allocating it. I don't know whether that makes a difference.
But the worst aspect is the initial value. new Foo generates a pointer to an object of type Foo. That is normally not a reasonable initializer in this context.
The meaning (if there is one) of this code is far enough from the intended meaning, I don't think I can guess the intended meaning. Maybe you should tell us what you want the code to do.
That declares an array whose size is not known until run time.
I'm not certain what the C++ standard says about that. But I think it says you can't do that.
When I've tried that, it has worked. I think it may be an extension to the language generally supported by compilers.
That is quite a bit less plausible.
It declares another array of the same name (that is not a problem because it is in an inner scope).
It obviously was intended to refer to an element of the first declaration, so the code is certainly wrong.
I've never tested the variable length local array feature inside a loop where the compiler would be unable to trivially manage the stack trick for allocating it. I don't know whether that makes a difference.
But the worst aspect is the initial value. new Foo generates a pointer to an object of type Foo. That is normally not a reasonable initializer in this context.
The meaning (if there is one) of this code is far enough from the intended meaning, I don't think I can guess the intended meaning. Maybe you should tell us what you want the code to do.
Well, if array is created at runtime, it's allocated, And allocation can fail, so the allocation result should be checked for not being NULL, which makes it look like traditional 'malloc' or 'new'.
I'm not certain what the C++ standard says about that. But I think it says you can't do that.
When I've tried that, it has worked. I think it may be an extension to the language generally supported by compilers.
I'm almost certain this is a gcc extension; it shouldn't compile. When in doubt, try it out.
To OP: You're on the right track as far as some objectives; you just need an array of pointers, not an array of objects, if you're going to use new like that. But normally one would just use an array of objects (like you've created,) which are already constructed unless they're "plain old data" (e.g. pointers, built-in numerical types.) Creating an array of pointers is most often used when you want an array of polymorphic objects, but even then containers are more often used.
Because you use input to determine the size, you're better off using std::vector and resizing it once the input comes. You should also check to make sure the value is > 0; keeping track of things like that becomes extremely important. Here is a good STL API reference.
If you're interested in exploring the dynamic allocation of it, try something like this:
Code:
int size;
cin >> size;
Foo *theArray = new Foo[size];
//...
delete[] theArray;
Think of delete as a trap set at all the exits to capture all escaping memory. If you allocate memory in a certain scope, make sure it's accounted for at all exits, e.g. return statements, loop exits, end of if/then statements (if applicable.) If you were to create an array of pointers (Foo *theArray[]) and you filled it with new objects (theArray[i] = new Foo) you'd have to go and delete each one exactly as you allocated them. You'd also have to make sure the empty elements were set to NULL; therefore, arrays of pointers are often a nightmare.
Although most tutorials dump all of namespace std into the global scope, namespaces are there for a reason; therefore, you should get in the habit of fully-qualifying your classes and functions (e.g. std::cin.)
Kevin Barry
Okay, so it's looking like vectors will be better in the long run... I'll look up the syntax for those and how to use them...
But in terms of the objects, the idea is that I don't know how many to declare, so I can't name them all. How do I reference them only in terms of their position within the vector?
it's looking like vectors will be better in the long run.
Vectors are usually better in cases where the element count of an array isn't know at compile time. With a vector, you don't even need to know the element count when you define the vector. You can change it later.
This thread already discussed the C99 feature of local (on the stack) arrays with sizes not known until run time. They work at least sometimes in some compilers in C and C++. But if the standard says it is wrong, they are probably best to avoid.
You can also use pointers with new and delete[] to correctly allocate arrays whose sizes are known when defined but not known at compile time. But that tends to be more difficult and less flexible than using vectors.
Quote:
I'll look up the syntax for those and how to use them.
If you know the size when you define it
Code:
std::vector<Foo> theArray(size);
If you don't know the size when you define it
Code:
std::vector<Foo> theArray;
Later
Code:
theArray.resize(size);
There are lots of other methods available, but you could use a vector with just the above plus basic element access.
Quote:
How do I reference them only in terms of their position within the vector?
You had that almost correct in your first post theArray[i] is used to access the element at position i in an array or a vector named theArray.
You do not re specify the datatype when accessing an element that way. The compiler knows the datatype. theArray[i] references that element of a previously declared array or vector, but Foo theArray[i] declared a new array of i elements, each of which is of type Foo.
But you also need to know what can reasonably do with a reference to an element of an array or vector.
Code:
theArray[i] = new Foo;
was not a reasonable assignment because theArray[i] is a reference to a Foo but new Foo produces a pointer to a Foo.
When you set the size of a vector of Foo, all the objects in the vector are initialized by copying a default value. Depending on how Foo was defined, similar may be true for an array of Foo (all elements initialized by the default constructor as soon as the array is defined). So you might not even need that loop that seemed to be intended to set all the objects in the array to default initial value.
If you do need to set or reset an element to a copy of the value created by the default constructor, the syntax is
Perfect@ Thanks so much! That's exactly what I'm looking for.
One last question. How would I pass a vector as a parameter to a function. ie, if the vector was theArray, would I just do function(theArray)? In C++, are they passed by value, or by reference?
Everything in C is passed by value, whether that be an object or a pointer to one. In C++, references are a shortcut for passing using a pointer which allows you to avoid having to dereference it. If you're trying to pass an array, it's handled using a pointer to its first element. It all gets complicated after that: unlike in Java, you can arbitrarily nest pointers to the effect of "he said that she said that I said that this is the object," the last of which may be a reference (denoted by & instead of *.) It's probably best to stick with one or two levels of pointer-ing at this point.
Kevin Barry
How would I pass a vector as a parameter to a function.
Usually by reference. That is more efficient than passing by value and it allows the function to modify the contents (or even size) of the vector.
Quote:
In C++, are they passed by value, or by reference?
C++ passes by value unless the function declaration tells it to pass by reference.
Code:
typedef std::vector<Foo> myVector; // Using a typedef is cleaner than using std::vector<Foo> everywhere you need the type
void myFunction( myVector& passedVector ); // The & used that way means pass by reference
int main( int argc, char** argv ) {
...
myVector theVector(size); // Define the vector and its size
...
myFunction( theVector ); // The calling syntax for pass by reference is identical to pass by value
...
}
void myFunction( myVector& passedVector )
{
...
... passedVector[i] ... // The syntax inside the function is the same as for pass by value
...
}
At the places where you call a function, pass by reference looks the same as pass by value.
Inside the function where you use or modify the passed object the syntax is the same for pass by reference vs. pass by value. But the meaning is different. In pass by value, you are using or modifying a copy that ceases to exist when the function exits. In pass by reference, you are using or modifying the original.
The only syntax difference is the & added to the typename of the passed object in the argument list both where you declare the function and where you define the function.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.