Using functions from an objet inside an array of pointers - c++

How would it be possible to use tabEmployes[0].Function ???
CEmploye **tabEmployes[NB_EMPLOYES] = new CEmploye[NB_EMPLOYES];
int main()
{
for (int i = 0; i < NB_EMPLOYES - 1; i++)
{
int j = 0;
string sNom = *LES_EMPLOYES[i, j];
int iNum = atol(*LES_EMPLOYES[i, j + 1]);
int iNiv = atol(*LES_EMPLOYES[i, j + 2]);
CEmploye* unEmploye = new CEmploye(sNom, iNum, iNiv);
tabEmployes[i] = &unEmploye;
}

tabEmployees is an array of pointers to pointer. This means that tabEmployees[0] is a pointer to a pointer. To access the class methods you would have to dereference the pointer. You could use
(*(tabEmployees[0]))->methodName();
However, your current code points tabEmployees[0] to the memory address of a local variable, which will go out of scope at the end of the loop. This is undefined behavior and will most likely lead to undesired results (such as a crash, or all your pointers being the same).
I think you don't really want tabEmployees to be an array of pointers to pointers, especially as your code shouldn't compile right now.
This line:
CEmploye **tabEmployes[NB_EMPLOYES] = new CEmploye[NB_EMPLOYES];
should not compile, as you are assigning an array of pointers to an array of pointers to pointers.
As you are creating your pointers during the loop, it seems to me you don't need to assign any value to this array. If you change it to:
CEmploye **tabEmployes[NB_EMPLOYES];
Your code will now compile.
However, as I said above, you still have the problem that you are pointing to a local variable that will be going out of scope. I would suggest that your tabEmployees should be defined as:
CEmploye *tabEmployes[NB_EMPLOYES];
and assigned later as
tabEmployes[i] = unEmploye;
(note the removed &).
Now your array contains pointers to the newly allocated objects, rather than to the variable that pointed to that object. You would then access methods as follows
tabEmployes[i]->methodName();

Related

How to delete 1D array

I create an array like as below
int size = 5;
double my_arr[m_size];
for (int i = 0; i < size; i++)
{
my_arr[i] = (rand()%10+1) + ((double) rand() / (RAND_MAX));;
}
after doing some calculation on array I want to delete the array. So I do this
for (int i = 0; i < size; i++)
{
delete my_arr[i];
}
and I get this error
error: type ‘double’ argument given to ‘delete’, expected pointer
I searched internet and all solutions are related to pointer array. But I am not using any pointer. So how can I delete this array?
The array will be automatically deleted when leaving the scope in which the variable has been declared.
If you really need to free memory fast you can try put your code between embraces:
{ //create new scope
int size = 5;
double my_arr[m_size];
for (int i = 0; i < size; i++)
{
my_arr[i] = (rand()%10+1) + ((double) rand() / (RAND_MAX));;
}
//some stuff
} //all non-pointer objects (or arrays) will be deleted
Or you can use pointers :
double *pMyarr = new double[m_size] ;
First of all, I think you should consider using a memory leak detector in your programms, so you can know by yourself if your code is leaking and if you have to do something about it. In your code you would have seen that there is no need to delete anything. :)
As far as I know, you should worry about memory in only two cases:
You have allocated a C-style array with malloc or calloc. In this case, you need to use the function free to deallocate the array. But generally in C++, you don't want this. You prefer using a container like std::array or std::vector instead.
You have created a new instance of an class with new and you have got a pointer to this instance. In this case, you have to use delete on the pointer when you don't need this instance anymore. But generally in C++11 (or further), you don't want this. If you really have to use a pointer, you prefer creating a smart pointer like std::unique_ptr or std::shared_ptr which will handle the memory for you.
When you define a variable without using new, malloc or calloc, (for example int a = 1 ;), it will be automatically deleted when it goes out of scope. So you don't need to worry.
Here is a simple example of a variable going out of scope:
int a = 1 ;
{
int b = 1 ;
// b is implictly deleted here, just before the bracket.
}
a++; // It works, because a exists in this scope
b++; // It doesn't work, because b is out of scope.
// a is implicitly deleted here, assuming we are at the end of a function

C++ referencing an array of structs

I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.

Create pointer to pointer in while statement issue

in Visual Studio 2010 i create a while statement in which i assign a pointer to pointer to a map.
Example:
std::map<int,std::tuple<int,std::string>** > dmap;
int i=0;
while (i<3){
std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
dmap[i] = &t;
dmap[i + 1 ] = &t;
i++;
}
.
.
.
for (auto it = d.begin();it!=d.end();++it)
{
if(*(it->second) != nullptr){
delete *(it->second);
*(it->second) = nullptr;
}
}
The problem is that the address of &t is always the same and so at the end the map always contains , for all keys that i entered, the last *t value.
What's the problem? (Resolved)
[Edit]
Now i modify the code beacause before it was incomplete, if i want to avoid to delete nullptr i need to have a pointer to pointer. Or not?
The problem is that you're putting a pointer to a local variable t into the map. After each loop, t is destroyed and the pointer is no longer valid.
I've no idea why you're using pointers at all, let alone pointers to pointers. You probably want to put the tuples themselves in the map:
std::map<int,std::tuple<int,std::string>> dmap;
for (int i = 0; i<3; ++i){
dmap[i] = {10+i, "test"};
}
i create a while statement in which i assign a pointer to pointer to a map
Sorry for saying this, but it sounds to me like you have bigger problems than the fact that t is the same (this looks like the xy problem).
Consider (in order) one of these alternatives:
store your tuples by value
store your tuples by single pointer (worse than "by value", better than "by pointer to pointer"). If you can do this, consider declaring your map over std::shared_ptr<std::tuple<...>>)
if you really need a map of pointers to pointers to tuples, consider creating a minimal proxy object that acts like a smart pointer to pointer internally (and manages the allocations for you in a safe manner) and like a regular type from the outside (and redeclare your map accordingly).
Either way, if you really need a map of pointers to pointers to tuples (for some reason), the allocation should be done like this:
std::map<int,std::tuple<int,std::string>**> dmap;
int i=0;
while (i<3) {
*dmap[ i ] = new std::tuple<int,std::string>{10 + i, "test"};
++i;
}
(The way you did it added the address of the same local (stack) variable to the map, which would lead to undefined behavior after you exit the local function).
Why are you interested in std::tuple<int,std::string>** ?
Wouldn't a std::tuple<int,std::string>* be sufficient ?
std::map<int,std::tuple<int,std::string>* > dmap;
int i=0;
while (i<3){
std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
dmap[i] = t;
i++;
}
Well, the address of t is always the same, because it is local variable that is stored on your stack. Each time you enter the block, t will be allocated on the same spot (as you're destroying t after you get out of your while body).
Instead, you need to allocate it on the heap (if this is really what you want to do).
std::tuple<int,std::string>** t = new std::tuple<int,std::string>*();
*t = new std::tuple<int,std::string>(10+i,std::string("test"));
dmap[i] = t;
I can't see what you're trying to accomplish, but this would be a better solution:
std::map<int,std::tuple<int,std::string>* > dmap;
int i=0;
while (i<3){
std::tuple<int,std::string>* t = new std::tuple<int,std::string>(10+i,std::string("test"));
dmap[i] = t;
i++;
}
Even better would be to use smart pointer instead raw one.
Even better would be to store objects by value (no pointers at all).

Assigning dynamically allocated array of pointers

Having a lot of trouble with this after sifting through many posts on here. Everything compiles but I get a crash right here during this function which should be dynamically allocating the addresses of one array into this array of pointers. I see one or two memory addresses posted so I'm not sure why it would be crashing during the middle of this.
string *copyArray(string ptrArray[],int sizeArray)
{
string **dynamString = new string*[sizeArray];
int i;
for (i=0;i<=sizeArray;++i)
{
(*dynamString[i]) = ptrArray[i];
cout << dynamString[i];
}
return *dynamString;
}
from main I have:
string *arrPtr;
and the function call
arrPtr = copyArray(arrayOfStrings, arraySize);
for (i=0;i<=sizeArray;++i)
accesses an element behind the array yielding an undefined behavior. Elements are indexed from 0 to sizeArray - 1. Another problem is that you allocate the array of pointers:
string **dynamString = new string*[sizeArray];
and then you are derefencing these pointers although they do not point to any object yet:
(*dynamString[i]) = ptrArray[i];
which also causes an undefined behavior. In case you wanted to create a deep copy, you should allocate the memory for every object as well:
for (i = 0; i < sizeArray; ++i)
{
dynamString[i] = new std::string(ptrArray[i]);
cout << *dynamString[i];
}
However you should avoid using C-style arrays always when it is possible and prefer STL containers instead. In this case it could be neat std::vector<std::string> and its constructor that would do the same than your function (just in safer and more reasonable manner with no possible memory leaks):
std::vector<std::string> myStrings(arrayOfStrings, arrayOfStrings + arraySize);
ok I fixed it here. My pointer syntax was incorrect. Here is the correct syntax.
dynamString[i] = &ptrArray[i];

Delete a pointer array without deleting the pointed objects in memory?

I would like to know if there is a way to delete a pointer array without touching the pointed objects in memory.
I'm writing a restriction routine for a HashSet I implemented a couple of days ago, so when the hash table is full it gets replaced by another double sized table. I'm representing the hash table using an array of pointers to an object (User), and the array itself is declared dynamically in my HashSet class, so it can be deleted after copying all its content to the new table using a hash function.
So basically I need to:
Declare another table with a size that equals the double of the original array size.
Copy every pointer to User objects from my original array to the new one applying my hash function (it gets the User object from memory and it calculates the index using a string that represents the user's name).
After inserting all the pointers from the original array to the new one, I will have to free the allocated memory for the original array and replace the pointer in my HashSet class (member private userContainer) with the location of the new one (array).
The problem is that if I use delete[] userContainer to free the allocated memory for it, it will also delete every object in memory so the newly created replacement array will point to freed positions in memory!
What you describe does not sound right.
Let's say you have a class A and you create an array of As with:
A** array1 = new A*[32];
Then fill it:
for(int i = 0; i < 32; ++i)
array1[i] = new A();
Doing a delete[] array1 does not free the elements of array1.
So this is safe:
A** array1 = new A*[32];
for(int i = 0; i < 32; ++i)
array1[i] = new A();
A** arary2 = new A*[64];
for(i = 0; i < 32; ++i)
array2[i] = array1[i];
delete [] array1;
for(i = 0; i < 32; ++i)
// do something with array2[i]
In general, when you delete an array of pointers, whatever objects the pointers pointed to remain in existence. In fact, this is a potential source of large memory leaks.
But in some sort of reference-counted environment (eg, Objective-C or Qt), when you delete an array OBJECT (vs a simple [] array) then the reference counts are decremented and the objects will be deleted if the count goes to zero.
But if you're restructuring a hash table you'd better have somehow saved the pointer values before you delete the array, or else all the addressed objects will be lost. As you save them you can increment their reference counts (if you do it right).
(It would help to know what language you're dealing with, and what you mean by "array".)
I don't think your problem exists. Here's a baby example to show that there's nothing to worry about:
Foo * brr[10];
{
Foo * arr[10];
// This is not touching the objects!
for (Foo * it = arr; it != arr + 10; ++it) *it = new Foo;
std::copy(arr, arr + 10, brr);
} // no more arr
for (Foo * it = brr; it != brr + 10; ++it) delete *it; // fine
You can copy the pointers around freely as much as you like. Just remember to delete the object to which the pointers point when they're no longer needed.
A perhaps trivial reminder: Pointers don't have destructors; in particular, when a pointer goes out of scope, nothing happens.
Do you know the difference between malloc/free, new/delete and new[]/delete[]?
I figure that you might want to not use new[]/delete[] in your situation, as you don't want destructors to be called I guess?