I am trying to define
Vertex[] total_vertices = new Vertex[no_vertice];
in C++. But when compiling I get this:
:568:8: error: expected unqualified-id before ‘[’ token
I need to declare an array of Vertices of size "no_vertice", and then use its "Length" method to get its size. Why is it not working?
In C++, the [] only goes after the variable name, not after the type (unlike Java or C#).
But that wouldn't work anyway, because you can't assign a pointer-to-first-element-of-an-array (returned by new) to an array. You need to use a pointer:
Vertex* total_vertices = new Vertex[no_vertice];
And make sure to delete[] it after you're done using it.
You say you need to use it's Length method, which has two problems:
Arrays don't have methods like they do in java; they're just blocks of memory in C++. If you want to use an array-like structure that has member functions, check out std::vector
You wouldn't need the Length method of an array even if they did have one (which they don't) because you already have the size in the variable no_vertice.
C++ arrays don't have length methods. You need to look at std::vector.
The right way to do it is.
Vertex *total_vertices = new Vertex[no_vertice];
However, in C++ builtin arrays have no Length method. They have no method at all since they are not classes. The "length" of it would be no_vertice.
You seem to be talking Java or C#...
You want
std::vector<Vertex> total_vertices(no_vertice);
and then use its size() method to get the size.
It's best to avoid using new directly unless there's no alternative - it's very easy to lose track of the object's ownership and end up with a memory leak.
You should probably do something like
boost::shared_array total_vertices( new Vertex[no_vertices] );
or
boost::scoped_array total_vertices( new Vertex[no_vertices] );
that way you don't have to worry about cleaning up after yourself and leaking memory.
http://www.boost.org
In C++, always use a vector rather than an array if a vector can do what you want. Because a vector provides an easy way and some useful methods (such as the size() you want). The most important thing is that a vector is safer than an array when you subscribe an element in it (vector has a end() method to make sure you can't access out of the range of it). So I think you should write this:
#include <vector>
std::vector<Vertex> total_vertices(no_vertice); //vector is a container so you should declare it with a specified type.
You can get more information about vector in the C++ reference of vector.
Related
I am trying to connect two existing codebases — one in C, the other in C++. The C++ code uses std::vector whereas the other one is based on arrays of double. I would like to pass arrays of double from the C code, perform operations on std::vectors in the C++ code, and eventually have these operations reflected in the arrays of double.
Is it possible to create a std::vector that matches the memory occupied by the array of double?
I have tried several options, but they all involve the creation of a new vector and a copy of the array of double into that vector. For instance:
void fcn(double* a, int sizeofa)
{
std::vector<double> vect_a;
vect_a.assign(a, a + sizeofa);
// operations on vect_a
for (int i=0;i<sizeofa;i++) { a[i] = vect_a[i]; }
}
As noted in the comments, std::vector manages its own memory, you can't make it use some other memory as the backing store (it would have no idea what to do if the size changed, among other issues).
But you may not need a vector at all; if you're just using vector for non-dynamic size related features, it's highly likely you could just use the functions from <algorithm> to perform the same work directly on the array that you wanted to use vector's methods to accomplish.
In C++, functions requiring a container often denote the container by Iterator pairs, which are templated. This is very convenient, especially when interfacing with external libraries, because an iterator isn't a type. It is a concept, which is just an interface that defines what a type should look like. Turns out, C style pointers are valid iterators. This means that you can use any C++ function that accepts an iterator with any C array.
So, now to answering your question. In other answers, it was made clear that you cannot make a std::vector control the memory allocated by a C array because a std::vector requires full ownership over the data because it wouldn't know how to deallocate it. You can copy the C array into a vector, but there is no point in using a std::vector unless you want it's resizing capabilities.
In summary: try not to pass std::vectors into functions because iterators are more generic. If you must avoid templates (virtual function, etc) than use a C style array because those are very flexible too, you can turn a std::vector into a C array, but the other way requires a copy.
I know this is hard if you have already made your code interface with std::vectors, in which case a copy is the only possible way. Prefer C style arrays when you don't need to resize the array, and maybe in the future std::array_view
I'm using user input to determine the size of my array.
This array will be used by another object.
Additionally, this will be looping so the user will potentially change the array size.
What's the best way to do this?
And since the array is used by an object, would it be better to pass the array in the constructor or pass the size and create the array in the class?
I was thinking some sort of a new delete array combination?
Am I off the mark here?
For generic, dynamic array-like needs, the best option is probably the std::vector class. Just create it where it is needed, I'd say into the class.
std::vector is a resizable array provided by the standard template library. To get it,
#include <vector>
There is plenty of material on the internet for how to use vectors, e.g. http://www.cplusplus.com/reference/stl/vector/ . Without further information, a good first start would be to use std::vector's inside of your container.
I want to call a function which requires an array of integers. How could I do this without creating a new array of integers every time I want to call the function?
This is what I want to do:
someFunction(new int[]{obj[0].getInt(), obj[1].getInt()});
instead of doing this:
int intArray[2] = {obj[0].getInt(), obj[1].getInt()};
someFunction(intArray);
Assuming you can use C++11, you can define somefunction to take an std::vector (or a std::vector const &) instead of an actual array, and then use:
somefunction({obj[0].getInt(), obj[1].getInt()});
Unlike Java, you do not need to use new on a regular basis in C++. In fact, in most well written code it's fairly unusual.
As an aside, you generally want to avoid C++'s built-in arrays, and C++11 makes it easier to do that, to the point that there's rarely a good reason to use them at all.
I have a struct defined as
struct Point {
int x, int y
}
I am getting an array of Points passed into a function, as well as an integer i that tells me how many elements the array contains. How in the world can I just add an element into the array? I realize there is no method to just add new elements, as arrays can't be dynamically resized, so I need to create a new one and copy each element over...but when I try to do the following:
Point newPoints[i+1];
I am told that it expects a constant value, which of course I can't give it since I need i+1, and i is variable. C++ makes me sad. (If it isn't obvious, I come from a land where some divine being manages all your objects for you...)
P.S. I must use arrays...forgot to mention that.
In standard C++, you cannot create an array with a run-time-set size. You will need to do one of:
Declare newPoints as a pointer and then allocate the value using new Point[i+1], applying delete [] to it later.
Declare newPoints using something like boost::scoped_array, which manages cleanup automatically.
Use a non-array, such as an std::vector; you can use &v[0] to get a pointer from that.
Use a non-standard extension, such as the one provided by GCC.
Afraid you're going to have to use a new/malloc on this one. i is only determined at runtime, so there's no way it can statically allocate the memory it needs on the stack at compile time.
The reason you must use a constant value is that the newPoints array is being created on the stack, and to do that the compiler must know how big it is going to be at compile time. To be able to specify a dynamic size you must use either new[] and delete[], or a dynamic data structure class (like from the STL).
I'd like to use a std::vector to control a given piece of memory. First of all I'm pretty sure this isn't good practice, but curiosity has the better of me and I'd like to know how to do this anyway.
The problem I have is a method like this:
vector<float> getRow(unsigned long rowIndex)
{
float* row = _m->getRow(rowIndex); // row is now a piece of memory (of a known size) that I control
vector<float> returnValue(row, row+_m->cols()); // construct a new vec from this data
delete [] row; // delete the original memory
return returnValue; // return the new vector
}
_m is a DLL interface class which returns an array of float which is the callers responsibility to delete. So I'd like to wrap this in a vector and return that to the user.... but this implementation allocates new memory for the vector, copies it, and then deletes the returned memory, then returns the vector.
What I'd like to do is to straight up tell the new vector that it has full control over this block of memory so when it gets deleted that memory gets cleaned up.
UPDATE: The original motivation for this (memory returned from a DLL) has been fairly firmly squashed by a number of responders :) However, I'd love to know the answer to the question anyway... Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?
The obvious answer is to use a custom allocator, however you might find that is really quite a heavyweight solution for what you need. If you want to do it, the simplest way is to take the allocator defined (as the default scond template argument to vector<>) by the implementation, copy that and make it work as required.
Another solution might be to define a template specialisation of vector, define as much of the interface as you actually need and implement the memory customisation.
Finally, how about defining your own container with a conforming STL interface, defining random access iterators etc. This might be quite easy given that underlying array will map nicely to vector<>, and pointers into it will map to iterators.
Comment on UPDATE: "Is there a way to construct a std::vector using a given chunk of pre-allocated memory T* array, and the size of this memory?"
Surely the simple answer here is "No". Provided you want the result to be a vector<>, then it has to support growing as required, such as through the reserve() method, and that will not be possible for a given fixed allocation. So the real question is really: what exactly do you want to achieve? Something that can be used like vector<>, or something that really does have to in some sense be a vector, and if so, what is that sense?
Vector's default allocator doesn't provide this type of access to its internals. You could do it with your own allocator (vector's second template parameter), but that would change the type of the vector.
It would be much easier if you could write directly into the vector:
vector<float> getRow(unsigned long rowIndex) {
vector<float> row (_m->cols());
_m->getRow(rowIndex, &row[0]); // writes _m->cols() values into &row[0]
return row;
}
Note that &row[0] is a float* and it is guaranteed for vector to store items contiguously.
The most important thing to know here is that different DLL/Modules have different Heaps. This means that any memory that is allocated from a DLL needs to be deleted from that DLL (it's not just a matter of compiler version or delete vs delete[] or whatever). DO NOT PASS MEMORY MANAGEMENT RESPONSIBILITY ACROSS A DLL BOUNDARY. This includes creating a std::vector in a dll and returning it. But it also includes passing a std::vector to the DLL to be filled by the DLL; such an operation is unsafe since you don't know for sure that the std::vector will not try a resize of some kind while it is being filled with values.
There are two options:
Define your own allocator for the std::vector class that uses an allocation function that is guaranteed to reside in the DLL/Module from which the vector was created. This can easily be done with dynamic binding (that is, make the allocator class call some virtual function). Since dynamic binding will look-up in the vtable for the function call, it is guaranteed that it will fall in the code from the DLL/Module that originally created it.
Don't pass the vector object to or from the DLL. You can use, for example, a function getRowBegin() and getRowEnd() that return iterators (i.e. pointers) in the row array (if it is contiguous), and let the user std::copy that into its own, local std::vector object. You could also do it the other way around, pass the iterators begin() and end() to a function like fillRowInto(begin, end).
This problem is very real, although many people neglect it without knowing. Don't underestimate it. I have personally suffered silent bugs related to this issue and it wasn't pretty! It took me months to resolve it.
I have checked in the source code, and boost::shared_ptr and boost::shared_array use dynamic binding (first option above) to deal with this.. however, they are not guaranteed to be binary compatible. Still, this could be a slightly better option (usually binary compatibility is a much lesser problem than memory management across modules).
Your best bet is probably a std::vector<shared_ptr<MatrixCelType>>.
Lots more details in this thread.
If you're trying to change where/how the vector allocates/reallocates/deallocates memory, the allocator template parameter of the vector class is what you're looking for.
If you're simply trying to avoid the overhead of construction, copy construction, assignment, and destruction, then allow the user to instantiate the vector, then pass it to your function by reference. The user is then responsible for construction and destruction.
It sounds like what you're looking for is a form of smart pointer. One that deletes what it points to when it's destroyed. Look into the Boost libraries or roll your own in that case.
The Boost.SmartPtr library contains a whole lot of interesting classes, some of which are dedicated to handle arrays.
For example, behold scoped_array:
int main(int argc, char* argv[])
{
boost::scoped_array<float> array(_m->getRow(atoi(argv[1])));
return 0;
}
The issue, of course, is that scoped_array cannot be copied, so if you really want a std::vector<float>, #Fred Nurk's is probably the best you can get.
In the ideal case you'd want the equivalent to unique_ptr but in array form, however I don't think it's part of the standard.