0 registered members (),
869
guests, and 1
spider. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Re: Multidimensional Array of STRINGS
[Re: PriNova]
#407160
09/07/12 18:06
09/07/12 18:06
|
Joined: Dec 2008
Posts: 1,218 Germany
Rackscha
Serious User
|
Serious User
Joined: Dec 2008
Posts: 1,218
Germany
|
@PriNova: What exactly does not work?
@EvilSOb: It doesnt matter if 3dgs frees the memory after exiting. WIndows does it anyway when the application exits
MY Website with news of my projects: (for example my current Muliplayer Bomberman, GenesisPrecompiler for LiteC and TileMaster, an easy to use Tile editor) Sparetime-Development
|
|
|
Re: Multidimensional Array of STRINGS
[Re: Rackscha]
#407161
09/07/12 18:19
09/07/12 18:19
|
Joined: Sep 2012
Posts: 74 Niedersachsen, Germany
PriNova
Junior Member
|
Junior Member
Joined: Sep 2012
Posts: 74
Niedersachsen, Germany
|
@Rackscha: this code works perfect
STRING **mystring[5][5]; //note the DOUBLE-'*'
int x,y;
int main()
{
mystring = sys_malloc(sizeof(STRING**) * 5);
for( y = 0; y < 5; y++)
{
mystring[y] = sys_malloc(sizeof(STRING*) * 5);
for( x = 0; x < 5; x++)
{
mystring[x][y] = str_create("");
}
}
}
but if i left the 1 line at its origin
STRING **mystring; //note the DOUBLE-'*'
it will not work. i think about dynamic creation of arrays. for example the user inputs at the enginescreen some numbers and the array-dimensions will create runtime with this input.
Last edited by PriNova; 09/07/12 18:20.
|
|
|
Re: Multidimensional Array of STRINGS
[Re: PriNova]
#407165
09/07/12 20:30
09/07/12 20:30
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
OK... Im watching this thread now. So I can answer questions. Ive attached a stand-alone script showing a two-dimensional STRING array in action. As a point of interest... My PREVIOUS code was INCORRECT... See if you can pick where. Heres the script...
#include <acknex.h>
#include <default.c>
//
STRING* **myString; //note the TRIPLE-'*' !!!NOT DOUBLE!!! - ask why!
//
int size_x=5, size_y=5; //here are the 'limits' of the array.
//
//
void main()
{
wait(1); draw_textmode("Times",0,24,100); int x,y;
//--------------------------------------------------------------------------------------
//Create and fill the array
myString = (STRING***)malloc(size_x*sizeof(STRING***)); //create the X index
for(x=0; x<size_x; x++)
{ myString[x] = (STRING**)malloc(size_y*sizeof(STRING**)); //create the y index
for(y=0; y<size_y; y++)
{
(myString[x])[y] = str_create("TEST_"); //fill each element of this X index
str_cat_num((myString[x])[y], "%.0fx", x);
str_cat_num((myString[x])[y], "%.0f", y);
}
}
//
// Display the array data as a grid
while(!key_esc)
{
for(x=0; x<size_x; x++) for(y=0; y<size_y; y++)
{ draw_text((myString[x])[y], x*150, y*50, COLOR_WHITE); }
//
wait(1);
}
}
PriNove:: Im not going to answer any of you questions from before this code. Go over and try this code first. Then ask questions that remain un-answerd and are not explained by this code... Rackscha:: Yeah. I know that. But JCL must have put in the 'GS-version' of malloc() and free() for SOME reason, Im just making guesses as the what they are. I SUSPECT it is the memory-freeing at engine exit, because before I started using sys_malloc, I would 'often' get engine crashes on exit if I had been sloppy and not free'd ALL the memory I had malloc'ed. The more memory I failed to free, the greater the chance of a crash. sivan:: Why didnt you point out my mistake? Or did you go straight to using structs rather than strings? That would have 'skipped' my mistake... Also as a belated reply... Its not covered in the manual because There is plenty information about C, C++, or Windows library functions on the Internet or in online C courses. It is highly recommended for adcanced lite-C programming to work through such a course or book and learn about malloc, memcpy and all the other library functions that you can use.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: Multidimensional Array of STRINGS
[Re: PriNova]
#407168
09/07/12 22:33
09/07/12 22:33
|
Joined: Sep 2012
Posts: 74 Niedersachsen, Germany
PriNova
Junior Member
|
Junior Member
Joined: Sep 2012
Posts: 74
Niedersachsen, Germany
|
i think i understand where the error were in the script (only wild guessing)
1.)triple '*' because, the first '*' is for pointer intializing and the other two for the two-dimensions
2.) i forgot the brackets: (myString[x])[y] = str_create("TEST_");
do i have to put everytime these brackets around my array, if i assign a variable? thanks alot that helped me, but don't ask me, why this additional brackets have to be. i think you know it better. and yes studing some books about should help :-)
Last edited by PriNova; 09/07/12 22:36.
|
|
|
Re: Multidimensional Array of STRINGS
[Re: PriNova]
#407170
09/07/12 23:14
09/07/12 23:14
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
1> Yes thats correct. My bad sorry. BTW the ARRANGEMENT of the three '*' is pretty immaterial. These four all work the same. "STRING*** myString;", "STRING* **myString;", "STRING** *myString;", and "STRING ***myString;". So find a format that suits you. I use the "* **" format so I know that the right-hand "*" is number of dimensions, and the optional left hand ones are required by EACH of the objects that the array will be 'built' of. ie: "STRING* **myString;" means create a two(**) dimensional array which contains an array built of "STRING*" objects. But what works for me might not suit you... So go with what works for you.
2> Im not actually sure WHAT yours would have done. But I SUSPECT it would have made a 5x5 array of dynamically-sized string arrays.
FYI:: This is what Ive been TOLD about the brackets from multiple reliable sources.
In STANDARD-C, fixed-sized multi-dimesnional arrays can be accessed via the 'arr[x][y]' syntax, whereas dynamic arrays must use the '( arr[x] ) [y]' syntax. Lite-C does the same in order to remain as Standard-C compatible as possible.
But Ive never used dynamic arrays in anything other than lite-c, so Ive never experienced the issue in standard-C. So I take it on faith...
I've come to the conclusion that this is because fixed-size multi-dimensional arrays are 'known' to the compiler, and so the compiler then knows how to reference the 'arr[x][y]' to the data-table that IT created itself.
Whereas with the dynamic arrays, the compiler doesnt know in which order you have/will create the indexs, so it doesnt know whether to treat the X or the Y as the 'primary' index. So it then needs the brackets to determine the 'order' of processing the lookups. Start creating arrays with more than two dimensions and things start getting even more tricky if there was NO brackets... This way, the deepest dimension within the brackets get processed first, of course.
But be aware, my conclusion is based on some knowledge, some faith, quite a few assumptions and a little guesswork.... In that order. And if I am wrong its 'not important' because it has NO impact on coding techniques.
I would like to know 'the truth' of course, but I dont NEED to...
I hope this explaination of my 'belief' is of some help to you...
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: Multidimensional Array of STRINGS
[Re: EvilSOB]
#407225
09/09/12 18:44
09/09/12 18:44
|
Joined: Sep 2012
Posts: 74 Niedersachsen, Germany
PriNova
Junior Member
|
Junior Member
Joined: Sep 2012
Posts: 74
Niedersachsen, Germany
|
hi EvilSOB, i studied the whole weekend about pointers and dynamic n-dimensional arrays. and, now, it is much more clearlier now, how they work and why they'll be needed, but the syntax with the brackets i never found in any book i read (and i read 3 books about pointers and multi-array). this must be c-lite syntax. if i understand it right, for an non-string array, a double '*' should do the work for a 2 dimensional array, or if we use single chars. now i feel like a master of pointers, because after studing, it sounds logical, but i'll be happy about my chrash in the future. hehe
Last edited by PriNova; 09/09/12 18:45.
|
|
|
Re: Multidimensional Array of STRINGS
[Re: PriNova]
#407229
09/09/12 20:41
09/09/12 20:41
|
Joined: Feb 2008
Posts: 3,232 Australia
EvilSOB
Expert
|
Expert
Joined: Feb 2008
Posts: 3,232
Australia
|
Pointers are evil, thats all I can say. You think you know them, and then they start doing silly sh*t is you get sloppy. So be CAREFUL and TIDY and you should avoid many nightmares... Just to clarify, where you say "non-string" does need expanding, just in case your understanding is incomplete... When you create a string variable with "STRING* filename;", notice how it ALREADY has an "*" in it? Thats because it is a POINTER to a STRING struct in memory somewhere. The 'somewhere' is supplied by the str_create function. Thats why the multi-dim string array needs the extra '*', because it is an array of POINTERS, not an actual array of DATA. You will see meny other game objects are defined as pointers too. ENTITY, BMAP, FONT, TEXT, custom structs, etc... These would all need the extra '*' too. If this was already obvious, I apologise. I just want to be sure you that you got the WHOLE picture. Also ... if you want to learn bad habits.. then read on... A couple of 'dirty tricks' I regularly use to avoid using the 'bracketed' syntax for multi-dim arrays are as follows.
ENTITY* **ent_grid; //the entity array we wish to access
...
(ent_grid[x])[y] = ent_create(blah,blah); // the CORRECT way to access it
var lifespan = (ent_grid[x])[y].skill22; // the correct way to access it
....... Evil Shortcut #1
ENTITY* **ent_grid; //the entity array we wish to access
ENTITY* _ent_grid(int x, int y) { return((ent_grid[x])[y]); } //lookup function
...
_ent_grid(x,y) = ent_create(blah,blah); // the dirty way #1 to access it
var lifespan = _ent_grid(x,y).skill22; // the dirty way #1 to access it
....... Evil Shortcut #2
ENTITY* **ent_grid; //the entity array we wish to access
#define _ent_grid(x,y) (ent_grid[x])[y] //re-syntax macro
...
_ent_grid(x,y) = ent_create(blah,blah); // the dirty way #2 to access it
var lifespan = _ent_grid(x,y).skill22; // the dirty way #2 to access it
Using either of these, your CODE is cleaner, but they really are BAD habits to get into. But I have so many bad habits already, what is a few more... I seem to remember Dirty Trick #1 had problems in certain situations, I just cant remember them, as I normally use #2, or correct syntax if it is for sharing.
"There is no fate but what WE make." - CEO Cyberdyne Systems Corp. A8.30.5 Commercial
|
|
|
Re: Multidimensional Array of STRINGS
[Re: EvilSOB]
#407230
09/09/12 20:51
09/09/12 20:51
|
Joined: Nov 2007
Posts: 2,568 Germany, BW, Stuttgart
MasterQ32
Expert
|
Expert
Joined: Nov 2007
Posts: 2,568
Germany, BW, Stuttgart
|
I seem to remember Dirty Trick #1 had problems in certain situations, I just cant remember them, as I normally use #2, or correct syntax if it is for sharing. #1 doesn't work with assigning values to the pointer because you can't assign anything to the return value of a function (it would not make any sense at all)
ENTITY *ent = _ent_grid(x,y);
ent = ent_create(...);
this would be the same as your assignment in #1, but ent is a temporary variable which would be deleted after those both operations...
|
|
|
|