size of a list using pointer in C++ - c++

How to get size of a list using pointer ? I have the following piece of code. I put few integers inside and later, tried to get the size of the list.
#include <iostream>
#include <list>
using namespace std;
int main ()
{
list<int>* t;
for (int i=1; i<10; ++i)
{
t->push_back(i*10);
}
cout<<"size:\t"<<t->size()<<endl;
return 0;
}

You need to initialise the pointer to actually point somewhere. That could be a dynamically-allocated list using new (in which case you should be using a smart pointer of some description), or it could be some other object that already exists (in which case this is "point"less, isn't it?).
Better yet, don't use a pointer:
list<int> l;
for (int i = 1; i < 10; ++i)
l.push_back(i*10);
cout << "size:\t" << l.size() << endl;

You haven't allocated t. Write list<int>* t = new list<int>; or better unique_ptr<list<int>> t (new list<int>); if you are in c++11 . But in this case allocating list on the stack will work better anyway.

Related

Passing and modifying array of vectors through functions in c++

(I'm from C background and new in C++ and its STLs)
I'm writing a C++ array of vectors that will be passed (as a reference of an array of vectors) through a function and will be processed in it.
In this case [in C] I would have passed a pointer to my custom data type (call by value under the hood.)
My code that's giving errors in compile time while trying to do so:
#include <cstdio>
#include <vector>
using namespace std;
/*
the problem is I can't get the syntax. vector<type> &var is
a reference to a single dimension array of vectors.
*/
void pass_arrayOf_vect(vector<int> &array, int lmt);
int main() {
int lmt = 10;
vector<int> lst[lmt];
pass_arrayOf_vect(lst, lmt);
return 0;
}
/*
and the traditional ambiguity of whether using "." or "->" for
accessing or modifying indexes and their members.
*/
void pass_arrayOf_vect(vector<int> &lst, int lmt) {
for (int i = 0; i < lmt; i++) {
lst[i].push_back(i*i);
}
for (int i = 0; i < lmt; i++) {
printf("array[%d]: ", i);
for (int j = 0; j < lst[i].size(); j++) {
printf("%d ",lst[i][j]);
}
printf("\n");
}
printf("\n");
return;
}
In the main function the lst variable is an array of vectors. When you pass this to the pass_arrayOf_vect function you pass a pointer to the first element.
I.e. when you do
pass_arrayOf_vect(lst, lmt);
it's actually the same as doing
pass_arrayOf_vect(&lst[0], lmt);
So the function you call needs to accept a pointer to a vector as its first argument (not a reference):
void pass_arrayOf_vect(vector<int> *array, int lmt);
// ^
// Note use of asterisk instead of ampersand
An even better solution would be to use an std::array of vectors instead. Or if you're on an older compiler without support for std::array, or need the amount to be run-time configurable (in which case you can't use plain C-style arrays anyway), use a vector of vectors.

C++ multi dimensional array of pointers without declaration

I want to declare multi dimensional (int his case two-dimensional) array. I can't declare size of global array. With one dimension, everything works:
#include <iostream>
#include <fstream>
using namespace std;
int N, M;
bool *table;
int main()
{
ifstream in ("in.txt");
in >> N >> M;
table = new bool[N];
return 0;
}
But if i want to declare two-dimensional array, I get an error:
'M' cannot appear in a constant-expression
#include <iostream>
#include <fstream>
using namespace std;
int N, M;
bool **table;
int main()
{
ifstream in ("in.txt");
in >> N >> M;
table = new bool[N][M];
return 0;
}
What is my option apart from declaring number instead of N and M, creating vector array or declaring table in main function?
What is my option apart from declaring number instead of N and M, creating vector array or declaring table in main function?
Allocate memory for N pointers.
For each pointer, allocate memory for M elements of type bool.
table = new bool*[N];
for (int i = 0; i < N; ++i )
{
table[i] = new bool[M];
}
When it's time to deallocate, use:
for (int i = 0; i < N; ++i )
{
delete [] table[i];
}
delete [] table;
You can avoid all the hassles of memory allocation and deallocation by using std::vector.
std::vector<std::vector<bool>> table(N, std::vector<bool>(M));
Use the old way of doing things: allocate a unidimensional array and afterwards access it by the unique index by doing the calculation (i*N+j). If you want to hide it create a function with two parameters for that.
If you want to avoid all the hassle of true multi-level arrays, you could:
int N=2, M=3;
bool *table = new bool[N*M];
// to access the element at (n,m):
ele = table[n*M + m];
This makes all the allocation/deallocation dead simple with the slight cost of having to type a bit more when accessing the elements. You could use a macro to fix that, of course.

Filling array of pointers by function c++

Hello I have made class gabka and a function f1 to which I would like to pass an array of pointers to fill this array with gabka objects but I get weird error. How to correct it?
error:
cannot convert from gabka to int
the code :
#include <iostream>
using namespace std;
const int n = 4;
class gabka {
public:
float woda;
gabka(){
woda = 0;
}
void f1(gabka t[n]){
for(int i = 0; i < n; i++){
t[i] = new gabka();
}
}
};
int main() {
gabka** t = new gabka*[n];
return 0;
};
Your f1 function takes an array of gabka objects, and you are trying to assign a gabka* to each one of them. You need to decide what you want to pass to f1. For example,
void f1(gabka t[n]){
for(int i = 0; i < n; i++){
t[i] = gabka(); // assign default constructed gabkas
}
}
or
void f1(gabka* t[n]){
for(int i = 0; i < n; i++){
t[i] = new gabka();
}
}
In the latter case, bear in mind you have to call delete on all the elements of t.
It isn't clear what you are intending to do with your code, but, as a general rule, in C++ you should avoid raw pointers and manual dynamic allocation. Prefer standard library containers over dynamically allocates arrays or arrays of dynamically allocated objects.
t[i] = new gabka();
t is an array of gabka, not an array of gabka*.
Either change the declaration of t to be an array of gabka*, or fill it with gabka instances.

Converting a vector to an array - Is there a 'standard' way to do this?

I know you can just do: &theVector[0], but is this standard? Is this behavior always guaranteed?
If not, is there a better, less 'hackish' way to do this?
Yes, that behavior is guaranteed. Although I can't quote it, the standard guarantees that vector elements are stored consecutively in memory to allow this.
There is one exception though:
It will not work for vector<bool> because of a template specialization.
http://en.wikipedia.org/wiki/Sequence_container_%28C%2B%2B%29#Specialization_for_bool
This specialization attempts to save memory by packing bools together in a bit-field. However, it breaks some semantics and as such, &theVector[0] on a vector<bool> will not work.
In any case, vector<bool> is widely considered to be a mistake so the alternative is to use std::deque<bool> instead.
C++11 provides the data() method on std::vector which returns a T*. This allows you to do:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vector = {1,2,3,4,5};
int* array = vector.data();
std::cout << array[4] << std::endl; //Prints '5'
}
However, doing this (or any of the methods mentioned above) can be dangerous as the pointer could become invalid if the vector is resized. This can be shown with:
#include <iostream>
#include <vector>
int main()
{
std::vector<int> vector = {1,2,3,4,5};
int* array = vector.data();
vector.resize(100); //This will reserve more memory and move the internal array
//This _may_ end up taking the place of the old array
std::vector<int> other = {6,7,8,9,10};
std::cout << array[4] << std::endl; //_May_ now print '10'
}
This could could crash or do just about anything so be careful using this.
We can do this using data() method. C++11 provides this method.
It returns a pointer to the first element in the vector. vector Even if it is empty, we can call this function itself without problems
vector<int>v;
int *arr = v.data();
A less 'hackish' way? Well you could simply copy :
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> vect0r;
int array[100];
//Fill vector
for(int i = 0; i < 10 ; i++) vect0r.push_back( i ) ;
//Copy vector to array[ ]
for( i = 0; i < vect0r.size(); i++) array[i] = vect0r[i];
//Dispay array[ ]
for( i = 0; i < vect0r.size(); i++) cout<< array[i] <<" \n";
cout<<" \n";
return 0;
}
More here : How to convert vector to array in C++

C++ public constructor address

After writing the code below:
#include <iostream>
using namespace std;
typedef struct Node {
int value;
Node(int index) {
value = index;
}
} Node;
int main() {
Node* arr[10];
for(int i = 0; i < 10; i++) {
arr[i] = &Node(i);
}
for(int i = 0; i < 10; i++)
cout << arr[i]->value << endl;
}
I saw that the code prints only 9's instead of all the numbers from 0 to 9 it was supposed to.
After debugging the code i saw that address of arr[i] for each i are the same, and Node(i) have freed the space for arr[i] only once, and after that the only thing it is value = index without freeing any other space. Why?
This line: arr[i] = &Node(i); is storing a pointer to a temporary object. Node(i) creates a temporary object that can be destructed at the end of the statement, at which point all references to it become invalid meaning the results of any code that dereferences arr[i] will be undefined. The reason in this case you get all 9's is because the compiler is optimizing the code -- since only 1 temporary Node(i) is being created at a time, the compiler is just reusing that memory each time through the loop.
To fix the problem, allocate memory off the heap for each object: arr[i] = new Node(i);. Then when you are done using them you will also need to remember to delete each one:
for (int i=0; i < 10; ++i) {
delete arr[i];
}
If you want to investigate farther, try adding some code to your Node class to see what's happening: for example print out the address of this in your constructor, and/or create a destructor that just prints a message out so you can see it being called.
To create new objects, use new Node(i) otherwise you are creating temporary objects on the stack which is why they are all the same.
Remember to call delete on each object that you get back from new.
&Node(i)
This expression creates a temporary variable and returns its address. The temporary is then destroyed, and the next time the expression is evaluated, another temporary is created in the same place — hence the identical addresses.
You should probably eliminate the use of pointers, and introduce a default value for Node.
#include <iostream>
using namespace std;
typedef struct Node {
int value;
Node(int index) {
value = index;
}
Node() : value( 0 ) {} // allow default construction
} Node;
int main() {
Node arr[10]; // default-construct array values
for(int i = 0; i < 10; i++) {
arr[i] = Node(i);
}
for(int i = 0; i < 10; i++)
cout << arr[i].value << endl;
}
Do not use new Node for each object individually. Always use a container object to manage a group of objects with similar semantics. You might use std::vector here, or std::array if you have it. The overhead introduced by std::vector will be less than that introduced by new.