• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 240
  • Last Modified:

Dynamic Pointers

Hello,

I have a class in which I wish to store a dynamic array of objects, such as:

class fruits
{
public:
string name;
};

class fruitType
{
public:
fruits *fruit;
int number_of_fruits; // stores the number i've already put in
}

Now, I figured from what I know about pointers, I could simply do:

void add_fruit(fruits new_fruit)
{
A = new fruits[4]; // 4 or whatever number_of_fruits is + 1
fruits[0].setValue("apples"); // errors here at run time, with cannot read memory

for(int i=0;i<4;i++)
// Here I want to copy each of the fruits[i]->name into A[i]->name but can't due to error above, which I suspect is the same reason it errors here

// Store the new array of objects A with the newly added new_fruit into fruitType->fruit
}

Any ideas?
0
drakkarnoir
Asked:
drakkarnoir
  • 8
  • 8
  • 2
1 Solution
 
imladrisCommented:
HMmmm.

You pass in an argument of new_fruit, but it doesn't appear to get used anywhere.

fruits is a class name. Thus fruits[0] doesn't really mean anything.
You allocated an array of fruits to A (A=new fruits[4];). I suspect you meant A[0].setValue.

Though fruit doesn't appear to provide a setValue method......
0
 
drakkarnoirAuthor Commented:
I was giving a general idea of the setup, setValue is a function that sets "name" in fruits to the value passed.

new_fruit is the fruits type I wish to store into fruitType->fruit, as I have in my comment there. I did not add the code to it as I believe the problem is inherent with the memory read access error at run time.
0
 
drakkarnoirAuthor Commented:
"new_fruit is the fruits type I wish to store into fruitType->fruit"

Just realized that's not making what I meant to say clear,

new_fruit is the fruits type I wish to "append" to A (A being a copy of the existing fruitType->fruit but with 1 extra space for new_fruit) and then set A equal to fruitType->fruit.
0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
mactep13Commented:
To follow your code, this is what your function should look like:

void add_fruit(fruit fruit_obj)
{
A = new fruit[4]; // Allocate 4 objects of type fruit on the heap
for (int idx = 0; idx < 4; idx++)
{
     A[idx].SetName(fruit_obj->Name);
}
0
 
mactep13Commented:
Sorry, the fruit_obj should be a ptr.
Function should look like add_fruit(fruit* fruit_Obj)
Also, get the name out of fruit_obj through some method.
0
 
drakkarnoirAuthor Commented:
Thanks mactep13 , that worked perfectly, except I don't think I made myself full clear on what I was trying to do, this is what I meant:

void fruitType::add_fruit(fruit *fruit_obj)
{
A = new fruit[4]; // Allocate 4 objects of type fruit on the heap
for (int idx = 0; idx < 4; idx++)
{
//     A[idx].SetName(fruit_obj->Name);
        A[idx].SetName(fruit[idx]->Name);  // read memory error
/// I want to loop through the fruit object array (fruitType->fruit and essentially copy it over to A, then I want to add/append the incoming fruit_obj to A and set A to fruitType->fruit
}
0
 
imladrisCommented:
HMmm.

The "fruit" in "A[idx].SetName(fruit[idx]->Name);" still doesn't exist. It is a class, not an object.

I think we need to clarify the objective here. In the original question, given the mention of "dynamic pointer", and the method being named "add_fruit", it appears that you have a collection of fruit, that you wish to expand one by one.

However, your subsequent remarks appear to indicate that you have an array of fruit that you simply wish to copy to A.

I'm not clear on what you really intend. The former makes more sense, but the latter is what you are explicitly asking for.

To make the copy work you would, of course, have to be passing an array of fruit into the add_fruit method. Given that you could write the method as:

void fruitType::add_fruit(fruit *fruit_obj)
{   A=new fruit[4];
    for(int idx=0; idx<4; ++idx)
    {   A[idx].SetName(fruit_obj[idx].Name);
    }
    return;
}

Note again, that this requires that a pointer to an array of fruit objects be passed in to the add_fruit method.

Even with that, I am still not clear on where A is declared. Or how it is going to be accessed again. Or what the point of the fruitType class was.
0
 
drakkarnoirAuthor Commented:
Ok here is the problem for which I am trying to get this working:

I have to store user input (more than just fruit name) into an array.

Now, I also have to be able to "expand" that array on the fly. In other words, it has to be a dynamic array.

What I thought a good way to do it would be:

Make a class called "fruits" which stores the attributes about the fruits (user input).

Make a class called "fruitType" which manipulates an array of "fruits" objects. IE, addfruit, etc. It would store this array of "fruits" objects in a variable called "fruit_object_array" (I think fruitType->fruit was confusing, so let's use this now). So if I were to break it down:

User types in fruit attributes.

A new "fruits" object is created and passed into addfruit().

addfruit() then makes a new "fruits" (called A) object array, to accomodate the incoming fruit_obj.

Copy the class objects in fruitType "fruit_object_array" into "A".

Now that "A" has whatever "fruit_object_array" had but gives us room to add 1 more "fruits" object, I can set the last variable in "A" to the incoming fruit_obj.

Somehow (this part is the most confusing to me) set "A" to "fruit_object_array" in fruitType, so that "fruit_object_array" now has the old elements + the newly added fruit_obj.
0
 
drakkarnoirAuthor Commented:
"A" is really just a temporary variable that holds just one more element that "fruit_object_array" allowed for previously, so that a new "fruits" object can be added to it. Note, I have to use these two classes at the minimum.
0
 
mactep13Commented:
I would suggest using a vector instead of the array. Vectors will resize automatically when you need more space. So do the following:

#include <vector>

std::vector<fruit> fruit_object_array;
Make him a global variable or make him alive for the scope of what you're doing.
Then, create
void add_fruit(fruit new_fruit_object)
{
       fruit_object_array.push_back(fruit_new_object);
}

If you want to access it, call at() function of the vector:

fruit fruit_to_get = fruit_object_array.at(index_of_vector_array);

That's all. Vector will take care of resizing the array for you.
You can dynamically create vector on the heap if you wish or dynamically create fruit objects on the heap as well.
vector<fruit*> fruit_array;
fruit* pFruit = new fruit;
fruit_array.push_back(pFruit);

If you have defined a destructor for the class, then you won't leak memory.

Hope this helps.
mactep
0
 
mactep13Commented:
If you have to use arrays, here is what you need to do

void add_fruit(fruit fruit_object)
{
temp array of fruit_array_object *A = new fruit[new_index];
for (int idx = 0; idx < fruit_array_object's size; idx++)
{
     A[idx] = fruit_array_object[idx];
}
A[idx] = fruit_object;
fruit_array_object = A;

Then, you'll end up with fruit_array_object that has increased by one and it now has an extra element of fruit_object in it. I believe that is what you want. If not, please clarify...

mactep
0
 
mactep13Commented:
Don't forget to delete A.
delete [] A;
And what I meant for new_index is the new size of the array. Probably 1 more than what it used to be. Also, what I meant for fruit_array_object's size is the previous size - i.e. probably 1 less than the new size.
0
 
drakkarnoirAuthor Commented:
Still getting the cannot read access memory mactep13, here is fruit_array_object in my class fruitType:

fruits *fruit_array_object;

I unfortunately have to use arrays.

This line:

temp array of fruit_array_object *A = new fruit[new_index];

I made:

fruits *A = new fruit[new_index];

Is that okay?
0
 
mactep13Commented:
Yes, that is fine. What about the rest?
0
 
drakkarnoirAuthor Commented:
I think it decides to bail out at this line right here:

A[idx] = fruit_array_object[idx];

The rest:

void fruitType::add_fruit(fruit fruit_object)
{
number_of_fruits++; // works as i expect it to
fruits *A = new fruit[number_of_fruits];
for (int idx = 0; idx < fruit_array_object's size; idx++)
{
     A[idx] = fruit_array_object[idx];
}
A[idx] = fruit_object;
fruit_array_object = A;
}

fruit_array_object is:

(public) fruits *fruit_array_object;

In fruitType
0
 
mactep13Commented:
Yes, the index is higher than what you have in the fruit_array_object! Idx is set at one more! It points to last element of A as A has one more element than fruit_array_object. After you run the loop, A should have copies of fruit_array_object. That is what you did in
for (int idx = 0; idx < fruit_array_object's size; idx++)
{
     A[idx] = fruit_array_object[idx];
}
now, the A[idx] points to last member in A array. You may assign the new value of fruit_object there. But do not try to access fruit_array_object[idx] at this time as idx is one more than the size of the fruit_array_object!!!
After you assigned fruit_object to the last element of A, you may not assign the value of A (Which points to A[0]) to the fruit_array_object. As these array values are in a row, the new fruit_array_object will now actually use the new A values.
Don't forget to delete the old fruit_array_object BEFORE assigning A to it! But after the loop.

for (int idx = 0; idx < fruit_array_object's size; idx++)
{
     A[idx] = fruit_array_object[idx];
}
delete [] fruit_array_object;
fruit_array_objevc = A;

I got to run home. If you have questions, you'll have to wait for an hour or so.
mactep
0
 
mactep13Commented:
Oh, and looking at you code above , in the loop, do this:
for (int idx = 0; idx <number_of_fruits-1 ; idx++)
{
     A[idx] = fruit_array_object[idx];
}
This is VERY important as you do not want to go higher than the elements of the previous array. But I think I already mentioned it so forgive me if I am going in circles. Does that make sense?
0
 
drakkarnoirAuthor Commented:
Doh! It was because the 0 index wasn't always defined, so I was attempting to write/access it! Hehe...it works perfectly, thank you much.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

  • 8
  • 8
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now