c++: new multi dimensional array of strings [duplicate] - c++

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ multi dimensional array
I'm trying to create a class that creates an arbitrary sized array of strings based on one of the objects constructor arguments.
Here, the code for the object constructor I'm trying so far:
commandSpec::commandSpec(int numberOfCommands)
{
std::string * commands = new std::string[3][numberOfCommands];
}
I get an error: 'numberOfCommands cannot appear in a constant expression', could someone show me the correct way to specify an array in an object that i dont know the size of until execution.
Thanks, j

This should probably be implemented as a structure and a vector, like this:
struct command {
std::string first;
std::string second;
std::string third;
};
commandSpec::commandSpec(int numberOfCommands)
{
std::vector<command> commands(numberOfCommands);
}
Of course, you should choose appropriate names for the members of command.

Variable length arrays are allowed only when allocating on heap.
You need to allocate the array in 2 steps - first allocate array with length 3 (from pointers) and then loop through the 3 elements and allocate new string for each.
I'd recommend you to use std::vector instead.

I would use a std::vector instead, makes life easier:
commandSpec::commandSpec(int numberOfCommands)
{
std::vector<std::vector<std::string>> mystrings(numberOfCommands);
}

Invert the order of the dimensions...
commandSpec::commandSpec(int numberOfCommands)
{
std::string (*commands)[3] = new std::string[numberOfCommands][3];
}
However, I highly recommend you consider using vectors instead.

Related

Fixed-size array of objects and sub-objects on the heap [duplicate]

This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 8 years ago.
I've searched and searched but haven't found anything that really clears up my confusion.
I'm representing a grid, and have two classes, e.g.:
class Term {
...
};
class GridPoint{
Term a;
Term b;
Term c;
...
};
I would like to have a large, fixed-size array on the heap, where each element of the array is a GridPoint, itself containing multiple Terms.
However, the following example will not compile:
GridPoint* pGrid = new GridPoint[100][100];
According to gcc:
error: cannot convert ‘GridPoint (*)[100]’ to ‘GridPoint*’ in initialization
First I would like to suggest not using new and delete in modern C++, instead use smart pointers or containers from the standard library that encapsulates this as e.g. std::vector.
That being said, to get your example to work you have to initialize an array of arrays in a loop like so:
GridPoint** pGrid = new GridPoint*[100];
for (std::size_t i = 0; i != 100; ++i) {
pGrid[i] = new GridPoint[100];
}
// Do something...
for (std::size_t i = 0; i != 100; ++i) {
delete[] pGrid[i];
}
delete[] pGrid;
For a better alternative simply use std::array or std::vector:
std::array<std::array<GridPoint, 100>, 100> pGrid;
Note: std::array encapsulates a static array that it uses to store its data. This means that if you allocate a std::array object with automatic storage duration its data will not be dynamically allocated (the data will not be on the "heap").
std::vector will however store its data using dynamic allocation.

Arrays Or Vectors? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When would you use an array rather than a vector/string?
What is the difference between std::array and std::vector? When do you use one over other?
I always use vectors (dynamic arrays) for everything, I never use normal arrays, is there any downside to this, for example, will there ever be a time when a vector will not suit, and a normal array will suit a function?
According to Bjarne Stroustrup, you should use vector over Array unless you have a really good reason to use an array.
In nearly all situations, vector is preferable. Its memory is allocated from the free store (designed for large allocations) and managed automatically; and you can easily get a pointer to the array itself if you need it.
You would use an array (either built-in or std::array) if:
The array size is known at compile time and not so large that it might blow the stack; and
The array has a fixed scope; and
Dynamic allocation is causing issues such as excessive run-time cost or heap fragmentation, and you don't want to use custom allocators to address these issues.
Vector is a dynamically growing array. Whereas arrays are static. You have to define a array at the beginning and cannot be reallocated.
With vectors you do not have the limitation of declaring a fixed size. You can start with a empty vector and keep it growing as long as you want.
Till date I have never found any situation where array is more suited. In fact I have found using vectors solves many of many problems which I face with an array.
I think its a very good practice to use vectors always.
Keep doing it!!!!
Use whatever best fits your situation, I have outlined one of my favourite benefits of a fixed size array below with a little example.
If you have an unknown size or may require an increase in storage at runtime you would be looking for a vector.
If you have a predetermined size you can use a std::array or even a raw C array (int foo[256]) which has benefits in code simplicity and speed. One of the best benefits here is if the data to be stored in the array is known then you can use a C style initialiser list removing any of the setup costs which would occur with a vector and open up space for the optimizer to make things faster while also being simpler to debug:
struct KeyPair { int key; string name; };
const KeyPair kFoo[] = { { 0, "0" }, { 1, "1" }, { 2, "2" } };
const string& getName( unsigned int key )
{
assert( key < (sizeof(kFoo)/sizeof(*kFoo)) ); // Check key is a valid index
assert( kFoo[key].key == key ); //< Sanity check - useful is key is an enum which could change
return kFoo[key];
}

How to create Array of Dynamic Arrays in C++

I am trying to learn C++ and trying to write a code for a simple hash table like following structure:
array[0][0] array[0][1] array[0][2]
key 1 value 1 value 2
array[1][0] array[1][1]
key 2 value 3
array[2][0] array[2][1] array[2][2]
key 3 value 4 value 5
means Array of Dynamic Arrays. Now, I can't understand how to define the array like that ?
Any help on this will be grateful.
If you really did need to create a dynamic array of dynamic arrays you would have to do it using the new keyword for both arrays. For example:
// an array of int pointers... each points to the start of an array
int** arrays = new int*[10];
arrays[0] = new int[99]; // populate the first element of the array of arrays
arrays[1] = new int[47]; // arrays don't have to be the same size.
Of course I highly recommend NOT doing this. You have to then remember to use delete[] on each member of arrays and on arrays itself.
Really you should use the built in std::vector type for this. It is why it is there (I voted for the other answers!).
Just as a note, this is not contiguous memory either. Also if you do want the member arrays to be the same size you could allocate their memory in a for loop.
In C++ you would use a std::vector<T> and nest two of them in order to get a 2D array.
std::vector<std::vector<my_type>> vec;
std::vector<my_type> v;
vec.push_back(v);
v.push_back(mytype);
Create a vector <vector <T> >.
For example
vector <vector <string> > array;
vector <string> temp;
temp.push_back(key1);
temp.push_back(value1);
temp.push_back(value2);
array.push_back(temp);
.
.
.
This is old, and I'm sure I'm not writing anything answer posters don't know in the back of their minds, but OP looks like he's doing an assignment for homework. My homework requires me to write out routines with out using any STL resources. In that case the only possible answer here is the first one. Homework in the beginning isn't about efficiency, it's demonstrating use of lesson material.
Unfortunately much of the time what they want you to demonstrate is never illustrated in the lessons.
Which brings OP's like this one to dig the web for hard to find reference. Hard to find because nobody really does it the way they are required to do it.
I followed this link because the title led me to believe I would find resource for a static array of dynamic arrays. So I will post that application incase anyone else is looking for that reference.
int main()
{
int* time[2];
int userInp;
userInp = 5;
time[0] = new int[userInp];
time[0][1] = 6;
cout << time[0][1];
delete time[0];
return 0;
}

Adding element to Array of Objects in C++

How do I add an element to the end of an array dynamically in C++?
I'm accustomed to using vectors to dynamically add an element. However, vectors does not seem to want to handle an array of objects.
So, my main goal is having an array of objects and then being able to add an element to the end of the array to take another object.
EDIT**
Sorry, its the pushback() that causes me the problems.
class classex
{
private:
int i;
public:
classex() { }
void exmethod()
{
cin >> i;
}
};
void main()
{
vector <classex> vectorarray;
cout << vectorarray.size();
cout << vectorarray.push_back();
}
Now I know push_back must have an argument, but What argument?
Now I know push_back must have an argument, but What argument?
The argument is the thing that you want to append to the vector. What could be simpler or more expected?
BTW, you really, really, really do not want exmethod as an actual method of classex in 99% of cases. That's not how classes work. Gathering the information to create an instance is not part of the class's job. The class just creates the instance from that information.
Arrays are fixed sized containers. So enlarging them is not possible. You work around this and copy one array in a bigger and gain space behind the old end, but that's it.
You can create a array larger than you currently need it and remember which elements are empty. Of course they are never empty (they at least contain 0's), but that's a different story.
Like arrays, there are many containers, some are able to grow, like the stl containers: lists, vectors, deques, sets and so on.
add a Constructor to set i (just to give your example a real world touch) to your example classex, like this:
class classex {
public:
classex(int& v) : i(v) {}
private:
int i;
};
An example for a growing container looks like this:
vector <classex> c; // c for container
// c is empty now. c.size() == 0
c.push_back(classex(1));
c.push_back(classex(2));
c.push_back(classex(3));
// c.size() == 3
EDIT: The question was how to add an element to an array dynamically allocated, but the OP actually mean std::vector. Below the separator is my original answer.
std::vector<int> v;
v.push_back( 5 ); // 5 is added to the back of v.
You could always use C's realloc and free. EDIT: (Assuming your objects are PODs.)
When compared to the requirement of manually allocating, copying, and reallocating using new and delete, it's a wonder Stroustrup didn't add a keyword like renew.

How to store an unknown number of elements in an array C++

Sorry if the title is not clear but I ll explain now my problem. I am new in C++.
I have created a class in C++. Instances of that class are the input of the program and they have to be stored in an array to perform the calculations. The problem is that the number of instances of that class that have to be defined by the user is fixed for a single run but can vary from run to run. Here an example:
#include <<blablah>blahblah>
int main()
{
int number_of_instances = 3;
MyClass first_instance(one_parameter_1, another_parameter_1);
MyClass second_instance(one_parameter_2, another_parameter_2);
MyClass third_instance(one_parameter_3, another_parameter_3);
///////////////////
NOW I HAVE TO STORE ALL THREE IN AN ARRAY LIKE
MyClass array[number_of_instances] = {first_instance, second_instance, third_instance};
THE PROBLEM IS THAT I DO NOT KNOW BEFORE HAND HOW MANY OF THEM ARE THE USER IS GOING TO INPUT
///////////////////
performCalculations(array);
return 0;
}
Thanks a lot in advance.
The typical C++ solution is to use a vector.
vector<MyClass> v;
v.push_back(first_instance); //add an already instantiated object to the end of the vector
v.push_back(second_instance);
v.push_back(third_instance);
You won't have to worry about memory management and you are able to access the vector like you would a normal array:
v[0].classMember
You can also add items to the vector in a loop if needed like so:
for(int i = 0; i < 5; i++){
v.push_back( MyClass(i, param2) );
}
And all the objects will be destructed when the vector goes out of scope if you're storing the objects directly in the vector.
One of the downsides to storing the objects directly in the vector is passing the vector as a parameter to a function. This will be a slow operation since the vector (and all the objects it holds) will have to be copied.
If you know the number of instances before you read them all in then you can allocate an array on the heap using new[]. (Don't forget to delete[] them when you've finished.) Note that this requires that the object have a default constructor.
you should use std::vector in this case rather than a built-in array.
#include <vector>
...
std::vector<MyClass> v = {first_instance, second_instance, third_instance};
...
v.push_back(fourth_instance);
If you don't know how many elements the array will contain, I would use a std::vector instead of a plain array as the vector will grow to accommodate the additional elements.
What you want is the Vector class from the standard template library, it behaves like an array but it will re-size itself if you fill it's internal allocation. If you do not need random access to it (i.e. use the [] opperator) you may want to use the List class instead. If you use List you will need to create an enumerator to step through it.
use std::vector<MyClass>, vector template can be found in <vector> header. YOu must learn a little bit to code well, before coding use any of online available c++ FAQs