Creating/resizing arrays...can't use non-constant? - c++

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).

Related

Why can't one dynamically declare an array of objects in C++ like this :

In my C++ project, there is a class which needs to create an array of objects.
Between different instances of the class, the size of the array will be different, which is why I chose to use an array.
If I do :
int numberOfPlayers; // This is determined at run time.
int *players;
//In constructor
players= new int[numberOfPlayers]; // This works
But if I do:
Character *players;
players = new Character[numberOfPlayers]; // Compiler complains
The Compiler complains "No matching constructor for initialisation of Character"
How do I dynamically declare an array of type "Character".
Note: Character has nothing to do with char. Character is a name of an class I created myself.
EDIT: Character does not have a default constructor, since it needs to be passed several arguments so it can be initialised with the proper state. The only constructor is has takes several arguments.
EDIT: I chose a dynamically created array, over a vector since I know during the lifetime of the instance, the size of the array will be constant, though between different instances the size will be different. I thought this would make sense for performance reasons (memory / speed).
The "proper" way is to use std::vector. It is a fast, safe, more robust alternative to horrible new.
std::vector<Character> vec;
vec.push_back(Character(params));
vec.push_back(Character(other_params));
If you know the size ahead, you can avoid reallocation overhead by using std::vector::reserve
std::vector<Character> vec;
vec.reserve(50);
vec.push_back(Character(params));
vec.push_back(Character(other_params));
The overhead of std::vector is practically non-existent.
Now, the reason why you can't do this your way, it's because by default new uses default constructor, and it doesn't exist.
The problem is that your type Character does not define a default constructor of the form:
Character::Character()
{
// etc.
}
Your type needs a default constructor. Unlike C's malloc, operator new constructs instances for you at the time of allocation. It then follows that it requires a parameterless (default) constructor as it provides no way to pass arguments. So...
class Character
{
public:
Character(){}
};
"Character does not have a default constructor, since it needs to be passed several arguments so it can be initialised with the proper state. The only constructor is has takes several arguments"
Then an array is the wrong type to use, because an array will always default-construct its members.
Use:
std::vector<Character> players;
The size can vary, as you wanted, and you can call players.push_back( character ) when each character has been constructed
The short answer is that you can't do this because the standard doesn't allow it. There's no technical reason it couldn't be allowed--it just isn't.
Some compilers (e.g., gcc) have supported it as an extension to C++ for years. It's also been supported in C by various compilers for long enough that C99 standardized it, so all (reasonably current) C compilers now support it.
There was a proposal to add an array-like class with a size determined when it was created, and remaining constant after that, but the committee decided against accepting it1. That leaves only std::array, which requires a size determined at compile time, and std::vector, with a size that can vary dynamically at run time.
In fairness, however, if you do know the size of a vector when you create it, you can specify the size at creation time. While it's certainly still capable of resizing itself, that functionality is mostly in resize and push_back. If you simply don't use those, the overhead from using std::vector compared to a native array is generally quite minimal anyway, so you're unlikely to see significant gains from other techniques (except, perhaps, under rather obscure circumstances).
1. At least IMO, this was the right decision--although I can see the basic reasoning behind the idea, I think the proposal was sufficiently flawed that we're better off without it.
Because allocating an array of Character means that the array will contain an amount of Character instances. When you allocate the array, each instance contained must be initialized somehow and the default constructor is required.
You have to declare Character::Character() { } to let the compiler invoke it. If you can't provide a default constructor then you should consider using a Character** so that you can init them as you wish, eg:
Character **array = new Character*[amount];
array[0] = new Character(...);
Mind that this requires to delete each instance, so instead of having delete[] array you will need
for (int i = 0; i < amount; ++i)
delete array[i];
delete [] array;
An additional way would be to forget about arrays and use a std::vector:
vector<Character> character;
character.push_back(Character(...));
Which would also relief the need to manage memory by yourself.

Array of structures in C++

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.

C++ Array of objects at two times

I have a class Agent, which contains a pointer (array) of class ValueContainer.
Now what I have to do is to create an array of Agent first, and then initialize each one of them independently. Also, Agent has no empty constructor due to its nature.
It's more or less like this:
Agent agent[n];
for (int i...)
{
load values from hd;
create a ValueContainer with this values;
initialize Agent[i] with loaded values;
deallocate the upstated ValueContainer;
}
// agent's constructor copies the VC values in his own VC,
// so there is no problem of pointers
Unfortunately, I keep on running in segmentation fault errors. I tried allocating the array with malloc, with the upstated declaration, making it an array of pointers. Still, I don't have any results.
Saying that you want to create an array of Agent without initializing those agents is an anachronism. Initialization takes place during construction. You can't create a thing without doing some kind of initialization.
In almost every case, the "right" thing to do in C++ is to use a vector or some other Standard container for your array, and then push_back new elements as you create them. You should see if this is the right approach for you. Without knowing anything at all about your application, it probably is.
Maybe what you mean (or maybe what you want) is to create memory space for the array, and then initialize them as you load them. This is quite rare, but it does happen. In that case, first you can allocate a char buffer that is big enough to hold all your items:
char buf[correct_size];
...and then use placement-new to initialize your Agents within this buffer:
new (&buf[byte_index]) Agent(parameter_list);
This is tricky. You have to juggle several things when using placement new:
You need to make sure you use the right byte_index within the buffer.
You need to make sure you deallocate in the correct order: destroy the Agents first, then destroy the buffer they are in.
You have to explicitly call the destructor in order to destroy the Agents:
Example of #3:
Agent* agent = reinterpret_cast<Agent*>(&buf[byte_index]);
agent->~Agent();
This is risky code in about a million different ways. I can't stress strongly enough how no matter how space-age and tempting it may be to try to do this, you probably should not do it in production code. Using placement new should be a last resort when absolutely nothing else will work.

c++ vector construct with given memory

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.

C++: What are scenarios where using pointers is a "Good Idea"(TM)? [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Common Uses For Pointers?
I am still learning the basics of C++ but I already know enough to do useful little programs.
I understand the concept of pointers and the examples I see in tutorials make sense to me. However, on the practical level, and being a (former) PHP developer, I am not yet confident to actually use them in my programs.
In fact, so far I have not felt the need to use any pointer. I have my classes and functions and I seem to be doing perfectly fine without using any pointer (let alone pointers to pointers). And I can't help feeling a bit proud of my little programs.
Still, I am aware that I am missing on one of C++'s most important feature, a double edged one: pointers and memory management can create havoc, seemingly random crashes, hard to find bugs and security holes... but at the same time, properly used, they must allow for clever and efficient programming.
So: do tell me what I am missing by not using pointers.
What are good scenarios where using pointers is a must?
What do they allow you to do that you couldn't do otherwise?
In which way to they make your programs more efficient?
And what about pointers to pointers???
[Edit: All the various answers are useful. One problem at SO is that we cannot "accept" more than one answer. I often wish I could. Actually, it's all the answers combined that help to understand better the whole picture. Thanks.]
I use pointers when I want to give a class access to an object, without giving it ownership of that object. Even then, I can use a reference, unless I need to be able to change which object I am accessing and/or I need the option of no object, in which case the pointer would be NULL.
This question has been asked on SO before. My answer from there:
I use pointers about once every six lines in the C++ code that I write. Off the top of my head, these are the most common uses:
When I need to dynamically create an object whose lifetime exceeds the scope in which it was created.
When I need to allocate an object whose size is unknown at compile time.
When I need to transfer ownership of an object from one thing to another without actually copying it (like in a linked list/heap/whatever of really big, expensive structs)
When I need to refer to the same object from two different places.
When I need to slice an array without copying it.
When I need to use compiler intrinsics to generate CPU-specific instructions, or work around situations where the compiler emits suboptimal or naive code.
When I need to write directly to a specific region of memory (because it has memory-mapped IO).
Pointers are commonly used in C++. Becoming comfortable with them, will help you understand a broader range of code. That said if you can avoid them that is great, however, in time as your programs become more complex, you will likely need them even if only to interface with other libraries.
Primarily pointers are used to refer to dynamically allocated memory (returned by new).
They allow functions to take arguments that cannot be copied onto the stack either because they are too big or cannot be copied, such as an object returned by a system call. (I think also stack alignment, can be an issue, but too hazy to be confident.)
In embedded programing they are used to refer to things like hardware registers, which require that the code write to a very specific address in memory.
Pointers are also used to access objects through their base class interfaces. That is if I have a class B that is derived from class A class B : public A {}. That is an instance of the object B could be accessed as if it where class A by providing its address to a pointer to class A, ie: A *a = &b_obj;
It is a C idiom to use pointers as iterators on arrays. This may still be common in older C++ code, but is probably considered a poor cousin to the STL iterator objects.
If you need to interface with C code, you will invariable need to handle pointers which are used to refer to dynamically allocated objects, as there are no references. C strings are just pointers to an array of characters terminated by the nul '\0' character.
Once you feel comfortable with pointers, pointers to pointers won't seem so awful. The most obvious example is the argument list to main(). This is typically declared as char *argv[], but I have seen it declared (legally I believe) as char **argv.
The declaration is C style, but it says that I have array of pointers to pointers to char. Which is interpreted as a arbitrary sized array (the size is carried by argc) of C style strings (character arrays terminated by the nul '\0' character).
If you haven't felt a need for pointers, I wouldn't spend a lot of time worrying about them until a need arises.
That said, one of the primary ways pointers can contribute to more efficient programming is by avoiding copies of actual data. For example, let's assume you were writing a network stack. You receive an Ethernet packet to be processed. You successively pass that data up the stack from the "raw" Ethernet driver to the IP driver to the TCP driver to, say, the HTTP driver to something that processes the HTML it contains.
If you're making a new copy of the contents for each of those, you end up making at least four copies of the data before you actually get around to rendering it at all.
Using pointers can avoid a lot of that -- instead of copying the data itself, you just pass around a pointer to the data. Each successive layer of the network stack looks at its own header, and passes a pointer to what it considers the "payload" up to the next higher layer in the stack. That next layer looks at its own header, modifies the pointer to show what it considers the payload, and passes it on up the stack. Instead of four copies of the data, all four layers work with one copy of the real data.
A big use for pointers is dynamic sizing of arrays. When you don't know the size of the array at compile time, you will need to allocate it at run-time.
int *array = new int[dynamicSize];
If your solution to this problem is to use std::vector from the STL, they use dynamic memory allocation behind the scenes.
There are several scenarios where pointers are required:
If you are using Abstract Base Classes with virtual methods. You can hold a std::vector and loop through all these objects and call a virtual method. This REQUIRES pointers.
You can pass a pointer to a buffer to a method reading from a file etc.
You need a lot of memory allocated on the heap.
It's a good thing to care about memory problems right from the start. So if you start using pointers, you might as well take a look at smart pointers, like boost's shared_ptr for example.
What are good scenarios where using pointers is a must?
Interviews. Implement strcpy.
What do they allow you to do that you couldn't do otherwise?
Use of inheritance hierarchy. Data structures like Binary trees.
In which way to they make your programs more efficient?
They give more control to the programmer, for creating and deleting resources at run time.
And what about pointers to pointers???
A frequently asked interview question. How will you create two dimensional array on heap.
A pointer has a special value, NULL, that reference's won't. I use pointers wherever NULL is a valid and useful value.
I just want to say that i rarely use pointers. I use references and stl objects (deque, list, map, etc).
A good idea is when you need to return an object where the calling function should free or when you dont want to return by value.
List<char*>* fileToList(char*filename) { //dont want to pass list by value
ClassName* DataToMyClass(DbConnectionOrSomeType& data) {
//alternatively you can do the below which doesnt require pointers
void DataToMyClass(DbConnectionOrSomeType& data, ClassName& myClass) {
Thats pretty much the only situation i use but i am not thinking that hard. Also if i want a function to modify a variable and cant use the return value (say i need more then one)
bool SetToFiveIfPositive(int**v) {
You can use them for linked lists, trees, etc.
They're very important data structures.
In general, pointers are useful as they can hold the address of a chunk of memory. They are especially useful in some low level drivers where they are efficiently used to operate on a piece of memory byte by byte. They are most powerful invention that C++ inherits from C.
As to pointer to pointer, here is a "hello-world" example showing you how to use it.
#include <iostream>
void main()
{
int i = 1;
int j = 2;
int *pInt = &i; // "pInt" points to "i"
std::cout<<*pInt<<std::endl; // prints: 1
*pInt = 6; // modify i, i = 6
std::cout<<i<<std::endl; // prints: 6
int **ppInt = &pInt; // "ppInt" points to "pInt"
std::cout<<**ppInt<<std::endl; // prints: 6
**ppInt = 8; // modify i, i = 8
std::cout<<i<<std::endl; // prints: 8
*ppInt = &j; // now pInt points to j
*pInt = 10; // modify j, j = 10
std::cout<<j<<std::endl; // prints: 10
}
As we see, "pInt" is a pointer to integer which points to "i" at the beginning. With it, you can modify "i". "ppInt" is a pointer to pointer which points to "pInt". With it, you can modify "pInt" which happens to be an address. As a result, "*ppInt = &j" makes "pInt" points to "j" now. So we have all the results above.