PDA

View Full Version : Arrays and classes ?



jonas
10-19-2000, 12:34 AM
I have constructed a little class system for an openGL app I made. The problem I have is that in my header file (star.h) I have defined an array something like

stars [200];

But is it possible to change that value (200) from either my main.cpp or the star.cpp which star.h is refering to.

Or should I define the array from another place instead ? I hope I made my problem clear and that someone please could help me.

Bob
10-19-2000, 12:44 AM
No, it's not possible to change the size of the array in run time. However, instead of using an array of predefined size, you can allocate it dynamically in runtime. Then you can change it's size any time you want.

Change your prototype to



<whateverthestructurenameis> *star;

and then you just allocate the memory when you create it.



star = (<whateverthestructurenameis> *)calloc(numItems, sizeof(<whateverthestructurenameis> ));

Whenever the array need to change its size, just create a new one, copy the contents from the old, and assign the star pointer to the new array. And dot forget to free the memory too. The pointer should be defined in the same place as your array is currently defined in.

Rob
10-19-2000, 05:36 AM
Another option is to use the STL (standard template library), which is a bunch of C++ template classes for things like linked lists, vectors, binary trees, and so on. It is part of the C++ standard now, so your implementation should include it already. There is definitely a learning curve associated with the STL, but the functionality it opens up to the programmer is totally worth it.

For doing a resizable array, you would want to use the vector class, so do something like this (note, I didn't compile this, so there might be typos.

#include <vector.h>

vector <your_class> vect;

your_class data1, data2, data3; //....

// to add stuff:
vect.push_back(data1);
vect.push_back(data2);

// to access use it just like an array:
data3 = vect[0];

vect[1] = vect[0];

// to explicitly set the size (force a resize of the vector)
vect.resize(new_size);

// to get the current size use vect.size(), i.e.

for (int i = 0; i < vect.size(); i++){
cout << vect[i] << endl;
}
.
.
.
and so on. Like I said, the STL can be a bit awkward at first, particularly if you've never used templates. (though vectors are probably the easiest thing to use in the STL)

Good luck.

Inquisitor
10-19-2000, 06:58 AM
In stdlib.h you'll find little function realloc which does all you want:
Here is an example on how to use it:
(I assume your star-class is named "CStar")




#include <stdlib.h>

#define REALLOC_BLOCK_SIZE 64

bool ResizeStarArray(CStar **star_array,size_t new_nr_stars,size_t old_nr_stars)
{
if(new_nr_stars!=old_nr_stars) {
if(!new_nr_stars) {
if(*star_array) {
free((void*)*star_array);
*star_array=0;
}
} else {
size_t new_alloc_size=(new_nr_stars/REALLOC_BLOCK_SIZE+1)*REALLOC_BLOCK_SIZE;
size_t old_alloc_size=(old_nr_stars/REALLOC_BLOCK_SIZE+1)*REALLOC_BLOCK_SIZE;
if(new_alloc_size!=old_alloc_size) {
CStar *tmp=(CStar*)realloc((void*)*star_array,sizeof(CSt ar)*new_alloc_size);
if(!tmp) return false;
*star_array=tmp;
}
}
}
return true;
}



This one allows you to easily reallocate yozr array. It also avoids frequent reallocation by allocating hole blocks of 64 stars. Returns false if some memory problem occured.
Hope it helps and hope it's error-free (not tested http://www.opengl.org/discussion_boards/ubb/wink.gif )


[This message has been edited by Inquisitor (edited 10-19-2000).]

[This message has been edited by Inquisitor (edited 10-19-2000).]

Eric
10-19-2000, 07:52 AM
That might sound silly Bob, but why not using the "new" operator of C++ ? If jonas is using classes, he must be using C++ !

To use the "new" operator:

CObject *myArray;
int iArraySize=50;
myArray=new CObject[iArraySize];

And to delete it:

delete [] myArray;

Regards.

Eric

DFrey
10-19-2000, 08:10 AM
One speed tip, when resizing a buffer to a smaller size, you may want to keep the larger size if it is likely the buffer will be resized again to grow.

Bob
10-19-2000, 08:47 AM
Erm, yes of course Eric *slap self*

I'm an old C programmer, and quite recently converted to C++, mainly because there was a course at the university I had to read to be able to go to the heavier courses. So this is the way I realized C++ got some potetial. Still haven't converted completely to C++ yet, and still allocates memory with calloc http://www.opengl.org/discussion_boards/ubb/smile.gif

Anyways, new and delete is ofcourse as good as calloc and free http://www.opengl.org/discussion_boards/ubb/smile.gif

And with calloc you can allocate memory and clear it the same time. Very convenient. Can you do this with new without coding your own constructors? I don't know, tell me if it's possible.

Eric
10-19-2000, 11:36 PM
Hi Bob !

No you can't.... You have to use some kind of loop to fill your array...

Actually, the fastest way is to use memset (that's where you think knowing C is useful !!!).

I have read many things about new/delete operators ; I think they are not always the way to go (coz' you don't know how the compiler implements them !). I suppose sometimes it is better to define your own by using calloc...

But I prefer the "new" notation (it looks cleaner !).

Regards !

Eric

Inquisitor
10-20-2000, 08:47 AM
Hi Eric,


No you can't.... You have to use some kind of loop to fill your array...



CStar::CStar(void)
{
memset(this,0,sizeof(CStar));
}

Should do the same thing as calloc. No loop needed, at least if you modify your example to use new. Of course, if you allocate pointers to CStars using new CStar*[20] you'll have to loop through the array and reset it to zero (or use memset).

With kind regards,
Inquisitor

Inquisitor
10-20-2000, 07:02 PM
Hi Eric,

Well, I didn't read Bob's question that exactly (... "without coding your constructor" ). Just saw your "no you can't"!
Surely you're right: without coding your own constructor you've got to use memset.
Nevermind http://www.opengl.org/discussion_boards/ubb/rolleyes.gif !

Again, kind regards
Inquisitor


[This message has been edited by Inquisitor (edited 10-20-2000).]

jonas
10-21-2000, 12:14 AM
THANKS everyone ! Now I have a lot of different alternatives to look at. I think the "stuff = new cobject" is kinda similar to the java syntax I am used to so I am gonna try to make that one work. But anyways thanks again everyone.
http://home.student.uu.se/joli7469/

Bob
10-21-2000, 01:20 AM
First, sorry to you Jonas for me having this conversation in your topic, glad you found your solution atleast http://www.opengl.org/discussion_boards/ubb/rolleyes.gif

Second, I REALLY think it's bad you don't have the option to allocate cleared memory with new. I know it's possible to write constructors, and I know I can overload the global new/delete operator, but I really don't think this should be necessary. Even though new makes the code clearer, as you said Eric, and I agree, it does. But of you want to allcate cleared memory, it's more clear code with calloc than a combination of new and memset after each other. And I don't want to code new operator functions just to make a simple testapplication.

And sure calloc got a selfexplaining list of arguments: calloc(10, sizeof(MYSTRUCT)); - this line allocates 10 etities, each one got the size of a MYSTRUCT. Not too difficult to understand and read, but a LITTLE more complex that new though.

Anyways, enough of my talking about this here... http://www.opengl.org/discussion_boards/ubb/biggrin.gif