resizable array of pointers

Discussion in 'C++' started by Mark, Oct 5, 2006.

  1. Mark

    Mark Guest

    i need to make a class that can store anything (integers,objects,etc)
    it needs to maintain a list of pointers to these objects
    the list needs to be resized to accomodate more elements
    i can't use any special classes

    i just can't seem to figure it out.

    i've got a pointer,

    void *storage

    which will point to the start of the list

    then there will be one pointer, every 4 bytes (sizeof(void*))

    which i *think* i can access by doing

    storage[index*sizeof(void*)]

    i'm not sure if I need to cast that to a void pointer or not, since
    that's already what it's defined as...

    but then to resize this beast, i'm completely lost

    i create a new void pointer..

    void* temp = new void*[length]

    where length is the new size (how many pointers it will hold)

    which should allocate length*4 bytes of memory...

    and then i tried doing

    for(int i=0; i<count; i++)
    {
    temp = storage[i*size];
    }

    to copy the pointers over
    where count is the number of elements currently in the stash, but my
    compiler complains...

    `void*' is not a pointer-to-object type
    pointer of type `void *' used in arithmetic

    and...i don't really know what else to do.

    any help?
    Mark, Oct 5, 2006
    #1
    1. Advertising

  2. Mark

    David W Guest

    "Mark" <> wrote in message
    news:...
    > i need to make a class that can store anything (integers,objects,etc)
    > it needs to maintain a list of pointers to these objects
    > the list needs to be resized to accomodate more elements
    > i can't use any special classes
    >
    > i just can't seem to figure it out.
    >
    > i've got a pointer,
    >
    > void *storage


    A template would be much better. Then you can store an array of T* for almost any type T. If you use
    void* you'll need to cast from void* to the correct type whenever you read the array, which is
    pretty horrible. Anyway, I'll press on with your non-template version.

    > which will point to the start of the list


    It should be void **storage, not void*. Remember, the elements of the array are themselves void *,
    and 'storage' is a pointer to the first one, so it's void **.

    > then there will be one pointer, every 4 bytes (sizeof(void*))


    Forget bytes. You don't need to think about 'em.

    > which i *think* i can access by doing
    >
    > storage[index*sizeof(void*)]


    No, you can't dereference a void *, because then you'd get void, which doesn't exist and has no
    defined size to do arithmetic on. It works without arithmetic if 'storage' is void**, since
    dereferencing that gives void*, which does exist and has a size, i.e., storage[index] is all you
    need.

    > i'm not sure if I need to cast that to a void pointer or not, since
    > that's already what it's defined as...


    It shouldn't be defined as that, though.

    > but then to resize this beast, i'm completely lost
    >
    > i create a new void pointer..
    >
    > void* temp = new void*[length]


    No, void **temp = new void*[length];

    > where length is the new size (how many pointers it will hold)
    >
    > which should allocate length*4 bytes of memory...


    Forget bytes.

    > and then i tried doing
    >
    > for(int i=0; i<count; i++)
    > {
    > temp = storage[i*size];


    temp = storage;

    > }
    >
    > to copy the pointers over
    > where count is the number of elements currently in the stash, but my
    > compiler complains...
    >
    > `void*' is not a pointer-to-object type


    That's right. Again, void** would fix that.

    > pointer of type `void *' used in arithmetic
    >
    > and...i don't really know what else to do.
    >
    > any help?


    DW
    David W, Oct 5, 2006
    #2
    1. Advertising

  3. Mark

    David W Guest

    "David W" <> wrote in message news:WdgVg.16315$...
    > "Mark" <> wrote in message
    > news:...
    > > i need to make a class that can store anything (integers,objects,etc)
    > > it needs to maintain a list of pointers to these objects
    > > the list needs to be resized to accomodate more elements
    > > i can't use any special classes
    > >
    > > i just can't seem to figure it out.
    > >
    > > i've got a pointer,
    > >
    > > void *storage

    >
    > A template would be much better. Then you can store an array of T* for almost any type T. If you

    use
    > void* you'll need to cast from void* to the correct type whenever you read the array, which is
    > pretty horrible. Anyway, I'll press on with your non-template version.


    I was assuming here that in a given array the pointers are all to the same type. If the same array
    has pointers to different types then a template wouldn't work. Of course, with an array of void * to
    a mix of types you'd always have to know which void * pointed to which type and cast it
    appropriately when you read it.

    DW
    David W, Oct 6, 2006
    #3
  4. Mark

    peter koch Guest

    Mark skrev:
    > i need to make a class that can store anything (integers,objects,etc)
    > it needs to maintain a list of pointers to these objects
    > the list needs to be resized to accomodate more elements
    > i can't use any special classes
    >
    > i just can't seem to figure it out.
    >

    [snip]
    >
    > any help?


    Sure... std::vector<>

    /Peter
    peter koch, Oct 6, 2006
    #4
  5. Mark

    Ole Nielsby Guest

    Mark <> wrote:

    > i need to make a class that can store anything (integers,objects,etc)
    > it needs to maintain a list of pointers to these objects
    > the list needs to be resized to accomodate more elements


    You might want to use a vector<void*> of the Standard
    Template Library (STL). Vectors are essentially resizeable arrays.

    Your online docs - or STL tutorials - will have vector examples
    you can work from.

    At first glimse, it can seem a bit strange that you have to deal
    with iterators instead of pointers, but the iterators are really just
    pointers that are dressed up fancy for mating with STL algorithms.

    HTH/ON
    Ole Nielsby, Oct 6, 2006
    #5
  6. Mark

    Mark Guest

    peter koch wrote:
    >
    > Sure... std::vector<>
    >
    > /Peter


    Mark wrote:
    > i can't use any special classes


    i was referring specifically to vectors and such.
    but thanks for trying.
    Mark, Oct 6, 2006
    #6
  7. Mark

    Mark Guest

    David W wrote:
    > "Mark" <> wrote in message
    > news:...
    > > i need to make a class that can store anything (integers,objects,etc)
    > > it needs to maintain a list of pointers to these objects
    > > the list needs to be resized to accomodate more elements
    > > i can't use any special classes
    > >
    > > i just can't seem to figure it out.
    > >
    > > i've got a pointer,
    > >
    > > void *storage

    >
    > A template would be much better. Then you can store an array of T* for almost any type T. If you use
    > void* you'll need to cast from void* to the correct type whenever you read the array, which is
    > pretty horrible. Anyway, I'll press on with your non-template version.
    >
    > > which will point to the start of the list

    >
    > It should be void **storage, not void*. Remember, the elements of the array are themselves void *,
    > and 'storage' is a pointer to the first one, so it's void **.
    >
    > > then there will be one pointer, every 4 bytes (sizeof(void*))

    >
    > Forget bytes. You don't need to think about 'em.
    >
    > > which i *think* i can access by doing
    > >
    > > storage[index*sizeof(void*)]

    >
    > No, you can't dereference a void *, because then you'd get void, which doesn't exist and has no
    > defined size to do arithmetic on. It works without arithmetic if 'storage' is void**, since
    > dereferencing that gives void*, which does exist and has a size, i.e., storage[index] is all you
    > need.
    >
    > > i'm not sure if I need to cast that to a void pointer or not, since
    > > that's already what it's defined as...

    >
    > It shouldn't be defined as that, though.
    >
    > > but then to resize this beast, i'm completely lost
    > >
    > > i create a new void pointer..
    > >
    > > void* temp = new void*[length]

    >
    > No, void **temp = new void*[length];
    >
    > > where length is the new size (how many pointers it will hold)
    > >
    > > which should allocate length*4 bytes of memory...

    >
    > Forget bytes.
    >
    > > and then i tried doing
    > >
    > > for(int i=0; i<count; i++)
    > > {
    > > temp = storage[i*size];

    >
    > temp = storage;
    >
    > > }
    > >
    > > to copy the pointers over
    > > where count is the number of elements currently in the stash, but my
    > > compiler complains...
    > >
    > > `void*' is not a pointer-to-object type

    >
    > That's right. Again, void** would fix that.
    >
    > > pointer of type `void *' used in arithmetic
    > >
    > > and...i don't really know what else to do.
    > >
    > > any help?

    >
    > DW


    ahh.. i tried a double pointer the first time around, which compiled,
    but then i ran into another problem down the road.

    i thought i might just be able to just have a pointer to the start of
    the list, but i guess what i had was a pointer to a list of voids,
    which don't have a size, when i needed a pointer to a list of void*'s..


    kinda tough to think about when you have all these asterisks and
    brackets laying around.

    but thank you, this really helped clear things up. much appreciated.

    void ObStash::inflate()
    {
    cout << "inflating";
    length += increment;
    void** temp = new void*[length];
    for(int i=0; i<count; i++)
    {
    temp = storage;
    }
    cout << "inflated";
    }

    now i'm having a problem adding to the list (it crashes after printing
    "inflated")

    int ObStash::add(void *p)
    {
    if( count >= length ) inflate();
    storage[count] = p;
    count++;
    }

    but, i'll see if i can work this out first before i ask any more
    questions.

    the reason i was so fixated on size was because i had previously made a
    stash where all the data was copied into the list, so it was very
    dependant on the size of the object.

    i agree that templates would be a much better solution..but..that isn't
    an option right now.

    the lists actually aren't mixed btw :) it would be crazy to try and
    keep track of what each thing was pointing to..
    Mark, Oct 6, 2006
    #7
  8. Mark

    Mark Guest

    Mark wrote:
    > David W wrote:
    > > "Mark" <> wrote in message
    > > news:...
    > > > i need to make a class that can store anything (integers,objects,etc)
    > > > it needs to maintain a list of pointers to these objects
    > > > the list needs to be resized to accomodate more elements
    > > > i can't use any special classes
    > > >
    > > > i just can't seem to figure it out.
    > > >
    > > > i've got a pointer,
    > > >
    > > > void *storage

    > >
    > > A template would be much better. Then you can store an array of T* for almost any type T. If you use
    > > void* you'll need to cast from void* to the correct type whenever you read the array, which is
    > > pretty horrible. Anyway, I'll press on with your non-template version.
    > >
    > > > which will point to the start of the list

    > >
    > > It should be void **storage, not void*. Remember, the elements of the array are themselves void *,
    > > and 'storage' is a pointer to the first one, so it's void **.
    > >
    > > > then there will be one pointer, every 4 bytes (sizeof(void*))

    > >
    > > Forget bytes. You don't need to think about 'em.
    > >
    > > > which i *think* i can access by doing
    > > >
    > > > storage[index*sizeof(void*)]

    > >
    > > No, you can't dereference a void *, because then you'd get void, which doesn't exist and has no
    > > defined size to do arithmetic on. It works without arithmetic if 'storage' is void**, since
    > > dereferencing that gives void*, which does exist and has a size, i.e., storage[index] is all you
    > > need.
    > >
    > > > i'm not sure if I need to cast that to a void pointer or not, since
    > > > that's already what it's defined as...

    > >
    > > It shouldn't be defined as that, though.
    > >
    > > > but then to resize this beast, i'm completely lost
    > > >
    > > > i create a new void pointer..
    > > >
    > > > void* temp = new void*[length]

    > >
    > > No, void **temp = new void*[length];
    > >
    > > > where length is the new size (how many pointers it will hold)
    > > >
    > > > which should allocate length*4 bytes of memory...

    > >
    > > Forget bytes.
    > >
    > > > and then i tried doing
    > > >
    > > > for(int i=0; i<count; i++)
    > > > {
    > > > temp = storage[i*size];

    > >
    > > temp = storage;
    > >
    > > > }
    > > >
    > > > to copy the pointers over
    > > > where count is the number of elements currently in the stash, but my
    > > > compiler complains...
    > > >
    > > > `void*' is not a pointer-to-object type

    > >
    > > That's right. Again, void** would fix that.
    > >
    > > > pointer of type `void *' used in arithmetic
    > > >
    > > > and...i don't really know what else to do.
    > > >
    > > > any help?

    > >
    > > DW

    >
    > ahh.. i tried a double pointer the first time around, which compiled,
    > but then i ran into another problem down the road.
    >
    > i thought i might just be able to just have a pointer to the start of
    > the list, but i guess what i had was a pointer to a list of voids,
    > which don't have a size, when i needed a pointer to a list of void*'s..
    >
    >
    > kinda tough to think about when you have all these asterisks and
    > brackets laying around.
    >
    > but thank you, this really helped clear things up. much appreciated.
    >
    > void ObStash::inflate()
    > {
    > cout << "inflating";
    > length += increment;
    > void** temp = new void*[length];
    > for(int i=0; i<count; i++)
    > {
    > temp = storage;
    > }
    > cout << "inflated";
    > }
    >
    > now i'm having a problem adding to the list (it crashes after printing
    > "inflated")
    >
    > int ObStash::add(void *p)
    > {
    > if( count >= length ) inflate();
    > storage[count] = p;
    > count++;
    > }
    >
    > but, i'll see if i can work this out first before i ask any more
    > questions.
    >
    > the reason i was so fixated on size was because i had previously made a
    > stash where all the data was copied into the list, so it was very
    > dependant on the size of the object.
    >
    > i agree that templates would be a much better solution..but..that isn't
    > an option right now.
    >
    > the lists actually aren't mixed btw :) it would be crazy to try and
    > keep track of what each thing was pointing to..


    hahaha..

    oops.

    forgot the two most important lines.

    void ObStash::inflate()
    {
    cout << "inflating";
    length += increment;
    void** temp = new void*[length];
    for(int i=0; i<count; i++)
    {
    temp = storage;
    }
    delete [] storage;
    storage = temp;
    cout << "inflated";
    }

    (delete, and storage = temp)

    i am deleting it properly, right?
    Mark, Oct 6, 2006
    #8
  9. Mark schrieb:
    > hahaha..
    >
    > oops.
    >
    > forgot the two most important lines.
    >
    > void ObStash::inflate()
    > {
    > cout << "inflating";
    > length += increment;
    > void** temp = new void*[length];
    > for(int i=0; i<count; i++)
    > {
    > temp = storage;
    > }
    > delete [] storage;
    > storage = temp;
    > cout << "inflated";
    > }
    >
    > (delete, and storage = temp)
    >
    > i am deleting it properly, right?
    >


    You forgot the class definition and all the other things. How we are
    supposted to know what the class is doing and what could be wrong?

    --
    Thomas
    http://www.netmeister.org/news/learn2quote.html
    Thomas J. Gritzan, Oct 6, 2006
    #9
  10. Mark

    Mark Guest

    David W wrote:
    > "Mark" <> wrote in message
    > news:...
    > > i need to make a class that can store anything (integers,objects,etc)
    > > it needs to maintain a list of pointers to these objects
    > > the list needs to be resized to accomodate more elements
    > > i can't use any special classes
    > >
    > > i just can't seem to figure it out.
    > >
    > > i've got a pointer,
    > >
    > > void *storage

    >
    > A template would be much better. Then you can store an array of T* for almost any type T. If you use
    > void* you'll need to cast from void* to the correct type whenever you read the array, which is
    > pretty horrible. Anyway, I'll press on with your non-template version.
    >
    > > which will point to the start of the list

    >
    > It should be void **storage, not void*. Remember, the elements of the array are themselves void *,
    > and 'storage' is a pointer to the first one, so it's void **.
    >
    > > then there will be one pointer, every 4 bytes (sizeof(void*))

    >
    > Forget bytes. You don't need to think about 'em.
    >
    > > which i *think* i can access by doing
    > >
    > > storage[index*sizeof(void*)]

    >
    > No, you can't dereference a void *, because then you'd get void, which doesn't exist and has no
    > defined size to do arithmetic on. It works without arithmetic if 'storage' is void**, since
    > dereferencing that gives void*, which does exist and has a size, i.e., storage[index] is all you
    > need.
    >
    > > i'm not sure if I need to cast that to a void pointer or not, since
    > > that's already what it's defined as...

    >
    > It shouldn't be defined as that, though.
    >
    > > but then to resize this beast, i'm completely lost
    > >
    > > i create a new void pointer..
    > >
    > > void* temp = new void*[length]

    >
    > No, void **temp = new void*[length];
    >
    > > where length is the new size (how many pointers it will hold)
    > >
    > > which should allocate length*4 bytes of memory...

    >
    > Forget bytes.
    >
    > > and then i tried doing
    > >
    > > for(int i=0; i<count; i++)
    > > {
    > > temp = storage[i*size];

    >
    > temp = storage;
    >
    > > }
    > >
    > > to copy the pointers over
    > > where count is the number of elements currently in the stash, but my
    > > compiler complains...
    > >
    > > `void*' is not a pointer-to-object type

    >
    > That's right. Again, void** would fix that.
    >
    > > pointer of type `void *' used in arithmetic
    > >
    > > and...i don't really know what else to do.
    > >
    > > any help?

    >
    > DW


    okay..maybe you can help me here,

    the names are printing out properly, but the numbers (scores) are
    garbage.

    void Student::print()
    {
    cout << " name: " << name << endl;
    int sum = 0;
    for(int i=0; i<scores.getCount(); i++)
    {
    int score = *(int*)scores.fetch(i);
    cout << " score" << i+1 << ": " << score << endl;
    sum += score;
    }
    if( scores.getCount() > 0 )
    cout << " gpa: " << sum/(float)scores.getCount() << endl;
    else
    cout << " no scores" << endl;
    }

    fetched like so

    void* ObStash::fetch(int index)
    {
    return storage[index];
    }
    Mark, Oct 6, 2006
    #10
  11. Mark

    Mark Guest

    Thomas J. Gritzan wrote:
    > Mark schrieb:
    > > hahaha..
    > >
    > > oops.
    > >
    > > forgot the two most important lines.
    > >
    > > void ObStash::inflate()
    > > {
    > > cout << "inflating";
    > > length += increment;
    > > void** temp = new void*[length];
    > > for(int i=0; i<count; i++)
    > > {
    > > temp = storage;
    > > }
    > > delete [] storage;
    > > storage = temp;
    > > cout << "inflated";
    > > }
    > >
    > > (delete, and storage = temp)
    > >
    > > i am deleting it properly, right?
    > >

    >
    > You forgot the class definition and all the other things. How we are
    > supposted to know what the class is doing and what could be wrong?
    >
    > --
    > Thomas
    > http://www.netmeister.org/news/learn2quote.html


    that part seems to be working (or at least not crashing)
    storage is defined as
    void** storage;
    i'm just asking if that will delete all the pointers in storage,
    without leaving anything behind.

    but, if you really want to see the class definition

    // opstash.h
    #ifndef OBSTASH_H
    #define OBSTASH_H

    const int increment = 100;
    const int size = sizeof(void*);

    class ObStash
    {
    int length;
    int count;
    void** storage;

    public:
    ObStash();
    int add(void* p);
    void* fetch(int index);
    ~ObStash();
    int getCount();
    void inflate();
    };
    #endif


    // obstash.cpp
    #include "ObStash.h"
    #include <iostream>
    #include "Student.h"
    //#include <cassert>
    using namespace std;



    ObStash::ObStash() : count(0), length(0)
    {}

    ObStash::~ObStash()
    {
    // delete all the pointers...
    }



    void ObStash::inflate()
    {
    length += increment;
    void** temp = new void*[length];
    for(int i=0; i<count; i++)
    {
    temp = storage;
    }
    delete [] storage;
    storage = temp;
    }

    int ObStash::add(void *p)
    {
    if( count >= length ) inflate();
    storage[count] = p;
    cout << count << ":" << storage[count] << endl;
    count++;
    }

    void* ObStash::fetch(int index)
    {
    return storage[index];
    }

    int ObStash::getCount() {
    return count;
    }



    andddd...since i'll be adding students (as well as integers) to this
    stash...

    // student.h
    #ifndef STUDENT_H
    #define STUDENT_H
    #include <string>
    #include "ObStash.h"
    using namespace std;

    class Student
    {
    string name;
    ObStash scores;

    public:
    Student(string name);
    void print();
    void cleanUp();
    };

    #endif

    // student.cpp
    #include "student.h"
    #include <iostream>

    using namespace std;

    Student::Student(string name) : name(name)
    {
    int score;
    while(1)
    {
    cout << " score" << scores.getCount()+1 << ": ";
    cin >> score;
    if( cin.fail() )
    {
    cin.clear();
    string s;
    getline(cin,s);
    cout << " * bad input" << endl;
    continue;
    }
    if( score == -1 )
    break;
    else if( score < 1 || score > 5 ) {
    cout << " * wrong input" << endl;
    continue;
    }
    scores.add(&score);
    };
    }

    void Student::print()
    {
    cout << " name: " << name << endl;
    int sum = 0;
    for(int i=0; i<scores.getCount(); i++)
    {
    int score = *(int*)scores.fetch(i);
    cout << " score" << i+1 << ": " << score << endl;
    sum += score;
    }
    if( scores.getCount() > 0 )
    cout << " gpa: " << sum/(float)scores.getCount() << endl;
    else
    cout << " no scores" << endl;
    }
    Mark, Oct 6, 2006
    #11
  12. Mark

    David W Guest

    "Mark" <> wrote in message
    news:...
    >
    >
    > hahaha..
    >
    > oops.
    >
    > forgot the two most important lines.
    >
    > void ObStash::inflate()
    > {
    > cout << "inflating";
    > length += increment;
    > void** temp = new void*[length];
    > for(int i=0; i<count; i++)
    > {
    > temp = storage;
    > }
    > delete [] storage;
    > storage = temp;
    > cout << "inflated";
    > }
    >
    > (delete, and storage = temp)
    >
    > i am deleting it properly, right?


    Yes. new[] requires delete[].

    DW
    David W, Oct 6, 2006
    #12
  13. Mark

    David W Guest

    "Mark" <> wrote in message
    news:...
    >
    >
    > okay..maybe you can help me here,
    >
    > the names are printing out properly, but the numbers (scores) are
    > garbage.
    >
    > void Student::print()
    > {
    > cout << " name: " << name << endl;
    > int sum = 0;
    > for(int i=0; i<scores.getCount(); i++)
    > {
    > int score = *(int*)scores.fetch(i);
    > cout << " score" << i+1 << ": " << score << endl;
    > sum += score;
    > }
    > if( scores.getCount() > 0 )
    > cout << " gpa: " << sum/(float)scores.getCount() << endl;
    > else
    > cout << " no scores" << endl;
    > }
    >
    > fetched like so
    >
    > void* ObStash::fetch(int index)
    > {
    > return storage[index];
    > }


    My guess is that the numbers you are putting in there no longer exist, but you didn't include that
    code. If the ints are ordinary local variables they may have gone out of scope. You may need to
    create each int to be stored with 'new' if that's the case (and delete later).

    DW
    David W, Oct 6, 2006
    #13
  14. Mark

    Mark Guest

    David W wrote:
    > "Mark" <> wrote in message
    > news:...
    > >
    > >
    > > okay..maybe you can help me here,
    > >
    > > the names are printing out properly, but the numbers (scores) are
    > > garbage.
    > >
    > > void Student::print()
    > > {
    > > cout << " name: " << name << endl;
    > > int sum = 0;
    > > for(int i=0; i<scores.getCount(); i++)
    > > {
    > > int score = *(int*)scores.fetch(i);
    > > cout << " score" << i+1 << ": " << score << endl;
    > > sum += score;
    > > }
    > > if( scores.getCount() > 0 )
    > > cout << " gpa: " << sum/(float)scores.getCount() << endl;
    > > else
    > > cout << " no scores" << endl;
    > > }
    > >
    > > fetched like so
    > >
    > > void* ObStash::fetch(int index)
    > > {
    > > return storage[index];
    > > }

    >
    > My guess is that the numbers you are putting in there no longer exist, but you didn't include that
    > code. If the ints are ordinary local variables they may have gone out of scope. You may need to
    > create each int to be stored with 'new' if that's the case (and delete later).
    >
    > DW


    okay, that worked like a charm!

    now..last question..i hope.

    i've got my destructor

    ObStash::~ObStash()
    {
    delete [] storage;
    }

    but will that be sufficient to prevent leakage?

    since it's an array of pointers. i figure i would have to delete each
    pointer first, and then delete the array, since it's declared as void
    **storage, however.. i can't delete each pointer because they delete
    void* is undefined!

    but, from my understanding, it's not necessarily delete integers
    anyways..they'll take care of themselves..but the Student class
    however, is another story.

    class Student
    {
    string name;
    ObStash scores;

    public:
    Student(string name);
    void print();
    void cleanUp();
    };

    the string has it's own destructor i believe, and should clean up after
    it's self...

    the obstash's destructor should clean up the scores too i think..

    but what about when

    ObStash students;

    goes out of scope?

    do i need to call the destructor for each object individually or
    anything..? (delete each student manually) or..will they all die
    gracefully?
    Mark, Oct 6, 2006
    #14
  15. Mark

    Mark Guest

    Mark wrote:
    > David W wrote:
    > > "Mark" <> wrote in message
    > > news:...
    > > >
    > > >
    > > > okay..maybe you can help me here,
    > > >
    > > > the names are printing out properly, but the numbers (scores) are
    > > > garbage.
    > > >
    > > > void Student::print()
    > > > {
    > > > cout << " name: " << name << endl;
    > > > int sum = 0;
    > > > for(int i=0; i<scores.getCount(); i++)
    > > > {
    > > > int score = *(int*)scores.fetch(i);
    > > > cout << " score" << i+1 << ": " << score << endl;
    > > > sum += score;
    > > > }
    > > > if( scores.getCount() > 0 )
    > > > cout << " gpa: " << sum/(float)scores.getCount() << endl;
    > > > else
    > > > cout << " no scores" << endl;
    > > > }
    > > >
    > > > fetched like so
    > > >
    > > > void* ObStash::fetch(int index)
    > > > {
    > > > return storage[index];
    > > > }

    > >
    > > My guess is that the numbers you are putting in there no longer exist, but you didn't include that
    > > code. If the ints are ordinary local variables they may have gone out of scope. You may need to
    > > create each int to be stored with 'new' if that's the case (and delete later).
    > >
    > > DW

    >
    > okay, that worked like a charm!
    >
    > now..last question..i hope.
    >
    > i've got my destructor
    >
    > ObStash::~ObStash()
    > {
    > delete [] storage;
    > }
    >
    > but will that be sufficient to prevent leakage?
    >
    > since it's an array of pointers. i figure i would have to delete each
    > pointer first, and then delete the array, since it's declared as void
    > **storage, however.. i can't delete each pointer because they delete
    > void* is undefined!
    >
    > but, from my understanding, it's not necessarily delete integers
    > anyways..they'll take care of themselves..but the Student class
    > however, is another story.
    >
    > class Student
    > {
    > string name;
    > ObStash scores;
    >
    > public:
    > Student(string name);
    > void print();
    > void cleanUp();
    > };
    >
    > the string has it's own destructor i believe, and should clean up after
    > it's self...
    >
    > the obstash's destructor should clean up the scores too i think..
    >
    > but what about when
    >
    > ObStash students;
    >
    > goes out of scope?
    >
    > do i need to call the destructor for each object individually or
    > anything..? (delete each student manually) or..will they all die
    > gracefully?


    i know i'm spamming, but there's no edit button that i've discovered.

    the destructor doesn't seem to be called for each student, when obstash
    students goes out of scope

    Student::~Student()
    {
    cout << "killing student " << name << endl;
    }

    int main(int argc, char *argv[])
    {

    {
    ObStash students;

    // snip
    }
    // destructors ought to be called here?
    system("PAUSE");
    return EXIT_SUCCESS;
    }



    in fact.. only the destructor for ObStash students is called, the
    ObStash scores are not destructed either! i'm assuming they're not
    being destructed because the students aren't being destructed.

    modifying it as follows..

    int main(int argc, char *argv[])
    {

    {
    ObStash students;
    // snip
    for(int i=0; i<students.getCount(); i++) {
    delete (Student*)students.fetch(i);
    }
    }

    system("PAUSE");
    return EXIT_SUCCESS;
    }


    everything seems to get destructed. i'm not missing anything am i?

    thank you all for your help :)

    i have one class in java, and one class in c++ this semester.. i'm
    really starting to appreciate java..kinda.

    to delete a list in java, all you have to do is set the head to null (i
    think), and let the garbage collector clean up the huge amount of data
    you just tossed into space.
    Mark, Oct 6, 2006
    #15
  16. Mark

    David W Guest

    "Mark" <> wrote in message
    news:...
    > David W wrote:
    > >
    > > My guess is that the numbers you are putting in there no longer exist, but you didn't include

    that
    > > code. If the ints are ordinary local variables they may have gone out of scope. You may need to
    > > create each int to be stored with 'new' if that's the case (and delete later).
    > >

    >
    > okay, that worked like a charm!
    >
    > now..last question..i hope.
    >
    > i've got my destructor
    >
    > ObStash::~ObStash()
    > {
    > delete [] storage;
    > }
    >
    > but will that be sufficient to prevent leakage?


    Not if the objects pointed to were created with 'new'.

    > since it's an array of pointers. i figure i would have to delete each
    > pointer first,


    Yes, and to the correct type of pointer as well (the same type created with 'new').

    > and then delete the array, since it's declared as void
    > **storage, however.. i can't delete each pointer because they delete
    > void* is undefined!
    >
    > but, from my understanding, it's not necessarily delete integers
    > anyways..


    Yes it is.

    > they'll take care of themselves..


    No they won't. If they were created with 'new' they consume space in the free store like anything
    else until they are explicitly deleted.

    > but the Student class
    > however, is another story.


    A related story.

    > class Student
    > {
    > string name;
    > ObStash scores;
    >
    > public:
    > Student(string name);
    > void print();
    > void cleanUp();
    > };
    >
    > the string has it's own destructor i believe, and should clean up after
    > it's self...


    Yes, as part of the destruction of the Student.

    > the obstash's destructor should clean up the scores too i think..


    No, it shouldn't. It can't know the types really being pointed to by the array elements, and it
    can't know whether those objects were created with 'new'.

    > but what about when
    >
    > ObStash students;
    >
    > goes out of scope?
    >
    > do i need to call the destructor for each object individually or
    > anything..? (delete each student manually)


    Yes.

    > or..will they all die
    > gracefully?


    No.

    DW
    David W, Oct 6, 2006
    #16
  17. Mark

    neel Guest

    Mark wrote:
    > i need to make a class that can store anything (integers,objects,etc)
    > it needs to maintain a list of pointers to these objects
    > the list needs to be resized to accomodate more elements
    > i can't use any special classes
    >
    > i just can't seem to figure it out.
    >
    > i've got a pointer,
    >
    > void *storage
    >
    > which will point to the start of the list
    >
    > then there will be one pointer, every 4 bytes (sizeof(void*))
    >
    > which i *think* i can access by doing
    >
    > storage[index*sizeof(void*)]
    >
    > i'm not sure if I need to cast that to a void pointer or not, since
    > that's already what it's defined as...
    >
    > but then to resize this beast, i'm completely lost
    >
    > i create a new void pointer..
    >
    > void* temp = new void*[length]
    >
    > where length is the new size (how many pointers it will hold)
    >
    > which should allocate length*4 bytes of memory...
    >
    > and then i tried doing
    >
    > for(int i=0; i<count; i++)
    > {
    > temp = storage[i*size];
    > }
    >
    > to copy the pointers over
    > where count is the number of elements currently in the stash, but my
    > compiler complains...
    >
    > `void*' is not a pointer-to-object type
    > pointer of type `void *' used in arithmetic
    >
    > and...i don't really know what else to do.
    >
    > any help?
    neel, Oct 6, 2006
    #17
  18. Mark

    neel Guest

    link list

    i have a single link list with with 5 nodes .if 5 nodes address part
    pointing to 2nd node. then show there is a loop . code it in c.
    help me.
    neel, Oct 6, 2006
    #18
  19. Re: link list

    neel wrote:
    > i have a single link list with with 5 nodes .if 5 nodes address part
    > pointing to 2nd node. then show there is a loop . code it in c.


    For C questions please ask in comp.lang.c. Also, read the FAQ before
    posting (there and anywhere else). They won't do your homework just
    like we won't.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Oct 6, 2006
    #19
  20. Mark

    Mark Guest

    David W wrote:
    > "Mark" <> wrote in message
    > news:...
    > > David W wrote:
    > > >
    > > > My guess is that the numbers you are putting in there no longer exist, but you didn't include

    > that
    > > > code. If the ints are ordinary local variables they may have gone out of scope. You may need to
    > > > create each int to be stored with 'new' if that's the case (and delete later).
    > > >

    > >
    > > okay, that worked like a charm!
    > >
    > > now..last question..i hope.
    > >
    > > i've got my destructor
    > >
    > > ObStash::~ObStash()
    > > {
    > > delete [] storage;
    > > }
    > >
    > > but will that be sufficient to prevent leakage?

    >
    > Not if the objects pointed to were created with 'new'.
    >
    > > since it's an array of pointers. i figure i would have to delete each
    > > pointer first,

    >
    > Yes, and to the correct type of pointer as well (the same type created with 'new').
    >
    > > and then delete the array, since it's declared as void
    > > **storage, however.. i can't delete each pointer because they delete
    > > void* is undefined!
    > >
    > > but, from my understanding, it's not necessarily delete integers
    > > anyways..

    >
    > Yes it is.
    >
    > > they'll take care of themselves..

    >
    > No they won't. If they were created with 'new' they consume space in the free store like anything
    > else until they are explicitly deleted.
    >
    > > but the Student class
    > > however, is another story.

    >
    > A related story.
    >
    > > class Student
    > > {
    > > string name;
    > > ObStash scores;
    > >
    > > public:
    > > Student(string name);
    > > void print();
    > > void cleanUp();
    > > };
    > >
    > > the string has it's own destructor i believe, and should clean up after
    > > it's self...

    >
    > Yes, as part of the destruction of the Student.
    >
    > > the obstash's destructor should clean up the scores too i think..

    >
    > No, it shouldn't. It can't know the types really being pointed to by the array elements, and it
    > can't know whether those objects were created with 'new'.
    >
    > > but what about when
    > >
    > > ObStash students;
    > >
    > > goes out of scope?
    > >
    > > do i need to call the destructor for each object individually or
    > > anything..? (delete each student manually)

    >
    > Yes.
    >
    > > or..will they all die
    > > gracefully?

    >
    > No.
    >
    > DW


    hm.. I think I was getting confused with something else. thank you for
    your help.
    Mark, Oct 10, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Thiago Almeida

    Resizable columns on a web datagrid

    Thiago Almeida, Oct 15, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    728
    Thiago Almeida
    Oct 15, 2003
  2. Jonathan Wilson
    Replies:
    9
    Views:
    408
  3. Sean
    Replies:
    2
    Views:
    624
    loufoque
    Sep 24, 2006
  4. Piotrek

    pointers and array of pointers

    Piotrek, Apr 2, 2007, in forum: C Programming
    Replies:
    8
    Views:
    314
    Chris Torek
    Apr 6, 2007
  5. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    642
Loading...

Share This Page