Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Newcomers AppGameKit Corner / Tier 2 Question [Comparing uStrings]

Author
Message
boldpaste2
2
Years of Service
User Offline
Joined: 4th Apr 2019
Location:
Posted: 6th Jan 2021 02:34
Yo!

Trying to get into Tier 2 and I am struggling to understand the concept of running a comparator (==) for uString. Essentially, I do not understand why example 1 would return FALSE and example 2 would return TRUE. My full code is below using the working example 2. In example 1, I attempt to imbed the "GetStringToken" within the conditional whereas in example to, I pass it off to a local first before comparing.

Example 1 (FALSE)


Example 2 (TRUE)


Cybermind
Valued Member
18
Years of Service
User Offline
Joined: 28th Nov 2002
Location: Denmark
Posted: 6th Jan 2021 11:14 Edited at: 6th Jan 2021 11:31
I can't say for sure why the first one won't work and the second one will. However, agk::GetStringToken returns a pointer (an address that points to where the data was created in memory when running this command), therefore you should delete the data that was created in memory when running this command when you're done with the data. The first example, you don't store the pointer and therefore you will afterward have no way of finding that memory address again. In the second example, you store the pointer in StringToken and can therefore delete the data where the pointer points to, then set the pointer itself to NULL, when you're done with the data.

EDIT: My guess would be that in the first example, it compares your parameter string and a pointer itself (the pointer points to an address in memory where the actual data is stored, so basically a pointer is just an address to some location in memory which means you're comparing a string to a memory address). In the second example, you compare the stored data where the pointer points to the parameter string. Again, this is a guess, I'm not totally sure about this, others will most likely come and shed some light on this. However, you need to learn about pointers and returned pointers, because if you don't delete the data that was returned by a command, it will just stay in memory, and gradually your program will keep building up stored data that is never deleted and never used again. This is called a memory leak.
13/0
Raven
16
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 6th Jan 2021 12:07


Remember that what the String Functions return are *(char *) NOT uString (which is a class that automatically cleans itself up)... so while the data contained is the same, they're different from the Compiler perspective.
When doing an assignment (=) this will simply copy the data regardless of the actual data structure.
If you're working with values rather than pointers... this wouldn't work, it'd throw a conversion error; but as we're working with pointers (data addresses) then the Compiler doesn't know WHAT is at the other end of the address, so it'll treat the data at the other end by however you're access it.
In this case we're saying to access it as a uString and the (*) is just informing it to copy the data not the address.

Pointers can become confusing and complicated, esp. to those new to C / C++ Programming., if this seems a bit overwhelming just create a temporary variable that you assign the value to THEN copy it.
Of course you could just bracket the entire function with a * on the outside to say "This is Data" ... technically it'd work the same way, I'm just showcasing a way that allows you to understand better what's going on; we're converting so both sides of the comparitor are the same.
MadBit
Valued Member
Gold Codemaster
11
Years of Service
User Offline
Joined: 25th Jun 2009
Location: Germany
Posted: 6th Jan 2021 15:51
Hi,
As the two before me have already said, you are trying to compare a char* pointer with a uString.
Since uString does not have an == operator that accepts a char* value on the left side, the compiler should complain when building the program.
In any case, you will have a memory leak. The returned char* strings from GetStringToken and also ReadLine must be deleted with DeleteString.

GetFileExists should not work like this either. Because this function expects a char* parameter. Therefore, the line should look like this.

The same applies to OpenToRead.

Personally, I would rather work with char* pointers and with strcmp than with uStrings. (As long as UTF8 support is not required).

Your function would look like this or something similar. (not perfect und not tested)
Share your knowledge. It\'s a way to achieve immortality. (Tenzin Gyatso)
boldpaste2
2
Years of Service
User Offline
Joined: 4th Apr 2019
Location:
Posted: 7th Jan 2021 01:49 Edited at: 7th Jan 2021 03:10
Thanks everyone for the feedback. I went into C++ without knowing what pointers and references where. (I watched a video that showed a few examples on how to convert tier 1 code to tier 2 and those concepts were never explained). I also wasn't aware that C++ doesn't do any cleanup other than some of its own classes. Looks like I need to find some good reading material on C++ before I try to code anything with it.

Thanks again! Anybody know of a good reading material?

EDIT
So I reworked the code based on all of the above suggestions (and watching a ton of videos on pointers) and the comparators are now working. I converted all of the uString to char * and then compared the two results. Just a few questions. Did I do the cleanup correctly in this function? or will all of these declarations (including the int) become free when the program leaves this functions scope?)

MadBit
Valued Member
Gold Codemaster
11
Years of Service
User Offline
Joined: 25th Jun 2009
Location: Germany
Posted: 7th Jan 2021 05:04 Edited at: 7th Jan 2021 05:41
I thiunk you are on the right way.

But ...
For example
FileName = NULL;
This sets the FileName pointer to NULL, but does not free any reserved memory.

Normally you reserve memory with new or malloc/calloc. And this memory is freed with delete or free.
Every Agk function which returns a char* pointer reserves in this way a memory area for the string to be returned.
In the documentation it is written that this must be released with the function DeleteString.
instead of agk:: DeleteString(FileName) also delete [] FileName should work.

Note that if memory has been allocated with new, it must be freed with delete. If it was reserved with malloc/calloc then free it with free.

A good reference is this page. It is a reference not a tutorial
This site is also good.
Share your knowledge. It\'s a way to achieve immortality. (Tenzin Gyatso)
Raven
16
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 11th Jan 2021 18:13
Quote: "Normally you reserve memory with new or malloc/calloc. And this memory is freed with delete or free.
Every Agk function which returns a char* pointer reserves in this way a memory area for the string to be returned.
In the documentation it is written that this must be released with the function DeleteString.
instead of agk:: DeleteString(FileName) also delete [] FileName should work."


While to a degree you're right., because all BoldPaste2 is doing is creating Pointers (not Memory)... notice how it's a Direct Assignment, this actually means that the Allocated Memory is ONLY In-Flight during the Function; because it assume a Private (Local) Scope.
When the Function End then that Memory is no longer held by that Variable and the Application / OS will consider it "Free" Memory.

Allocation and Release of Memory is typically related to Scope unless you're manually doing it.
If you're not using "new" or "malloc( )"... then the Allocation only lasts for as long as the Variable does.

You have to remember A LOT of Reference Material is for C89 / C90 Compilers., and older Operating Systems; on top of this the assumption is that you're manually allocating Memory (and thus responsible for release as well).
As soon as you say "This Pointer is Null" the Operating System will say "Oh this Memory is no longer reserved... Mine!" but again ONLY if you haven't manually allocated it.
Of course you HAVE to be careful getting in the habit of this, and I wouldn't actually ever do this.

Instead leave it for the Operating System to clean up when the Application closes.
See the way you get Memory Leaks isn't from leaving Memory Allocated... but rather by removing all references to it.

Think about it like this... look at it like Coffee Cups at work.
Everyone has a Coffee or a Tea on their Break at work., so each person uses a Cup for that... now typically speaking everyone has a Cup that is "Theirs", at least for the Duration of Work... let's say it's common practise to put a sticker with your name on it during you shift.
Well; if this is done, then everyone on the later shift knows "Oh such-and-such is finished earlier, so I can clean this Cup and put my own name on it"; all is fine because you know what Cup are "In-Flight"
But there's ALWAYS that one person, who everytime they have a break just uses whatever Cup they want and peels off the sticker.

Well now you have a bunch of dirty cups, and NO idea whose they are.
That's essentially a Memory Leak. Eventually you're going to run out of Cups because NO ONE knows which are currently being used and which aren't.
Of course it would be the polite thing to do is take off the Sticker and Wash it up before you Leave; but let's say you have Kitchen Staff (Operating System) that will go around every few hours and clean up., well you get the point.

Do you understand what I mean?
MadBit
Valued Member
Gold Codemaster
11
Years of Service
User Offline
Joined: 25th Jun 2009
Location: Germany
Posted: 12th Jan 2021 09:58
I find your comparison with the coffee cup really funny and appropriate.

But I don't quite agree with this.
Quote: "While to a degree you're right., because all BoldPaste2 is doing is creating Pointers (not Memory)... notice how it's a Direct Assignment, this actually means that the Allocated Memory is ONLY In-Flight during the Function; because it assume a Private (Local) Scope.
When the Function End then that Memory is no longer held by that Variable and the Application / OS will consider it "Free" Memory.
"

You are right that it only creates the pointer variables (labels the coffee cup).
But the memory is provided by AGk (he goes to the coffee machine with the coffee cup and has the cup filled).
Now he works with the data (looks at the coffee).
Then he sets the pointer to NULL and leaves the function (tears off the sticker and leaves the room, leaving the full cup of coffee ).
The kitchen staff will not clean the cup until the end of the day. (When the application is finished).

Example:
Read = agk::ReadLine(FileID); (The coffee machine reserves memory for the coffee).
Read = NULL; (sticker is removed full cup remains)
Next run with new cup "Read"

If this is done to initialise the programme, one could ignore this.
But if strings are queried in the loop, you might have a problem.

When Agk returns a string with a function, it reserves memory with new char[string_length].
After that, Agk no longer takes care of this memory.
The operating system does not know whether you still need this memory as long as the application is running. (The kitchen staff does not know if you will finish your coffee before the end of the day. )

But if I'm wrong, you're welcome to prove me wrong.
Share your knowledge. It\'s a way to achieve immortality. (Tenzin Gyatso)

Login to post a reply

Server time is: 2021-04-23 09:47:10
Your offset time is: 2021-04-23 09:47:10