?
Solved

Dynamic Pointers

Posted on 2005-04-07
18
Medium Priority
?
234 Views
Last Modified: 2010-04-01
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
Comment
Question by:drakkarnoir
  • 8
  • 8
  • 2
18 Comments
 
LVL 16

Expert Comment

by:imladris
ID: 13729893
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
 

Author Comment

by:drakkarnoir
ID: 13729975
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
 

Author Comment

by:drakkarnoir
ID: 13730027
"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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 3

Expert Comment

by:mactep13
ID: 13730075
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
 
LVL 3

Expert Comment

by:mactep13
ID: 13730091
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
 

Author Comment

by:drakkarnoir
ID: 13730812
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
 
LVL 16

Expert Comment

by:imladris
ID: 13730937
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
 

Author Comment

by:drakkarnoir
ID: 13731075
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
 

Author Comment

by:drakkarnoir
ID: 13731111
"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
 
LVL 3

Expert Comment

by:mactep13
ID: 13731327
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
 
LVL 3

Accepted Solution

by:
mactep13 earned 2000 total points
ID: 13731365
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
 
LVL 3

Expert Comment

by:mactep13
ID: 13731385
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
 

Author Comment

by:drakkarnoir
ID: 13731530
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
 
LVL 3

Expert Comment

by:mactep13
ID: 13731604
Yes, that is fine. What about the rest?
0
 

Author Comment

by:drakkarnoir
ID: 13731624
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
 
LVL 3

Expert Comment

by:mactep13
ID: 13731697
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
 
LVL 3

Expert Comment

by:mactep13
ID: 13731715
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
 

Author Comment

by:drakkarnoir
ID: 13731733
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

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question