Memory leaks on PropertiesFile


#1

Hi,

I have one function that get the defs for my app this way:

ApplicationProperties appProperties;

PropertiesFile::Options options;
options.applicationName = ProjectInfo::projectName;
options.folderName = ProjectInfo::projectName;
options.filenameSuffix = "settings";
options.osxLibrarySubFolder = "Application Support";
appProperties.setStorageParameters(options);
PropertiesFile* props = appProperties.getUserSettings();

And the i get the property i want this way:

variable = props->getIntValue("TerminalType", 0);

What is happening is that when i close my app, it give me memory leaks, and they are related with the variable props, derived from PropertiesFile.

What should i do to fix this ?

Paulo

 

 


#2

Try using a ScopedPointer…

And if necessary make props a class variable, depending on the scope and lifetime of the variable

Rail


#3

Hi pvaz... 

Are you using the example out of the "Getting Started With JUCE" book?


#4

Hi Rick,

yes, i'm using it, i bought that book.

I've tried your suggestion but did not worked.

Paulo


#5

That book has been very helpful.  I would have been lost without it.  Sure there is the demo and it seems feature rich, but having something that you can read that leads you along the way is hugly benificial as well.   I'm hoping the guy who wrote that one writes another book.  And like yesterday cuz I just finished this one.  


#6

It's a good aproach to JUCE and encourages people to work with it.

But as you said, it's basic and it was important to have a more advanced version.

It's a start !


#7

Hi Rail,

did not worked. And even i moved inside a class and gives me the same.

If I use ScopedPointer it's crashes the application.

I really do not understand what can be wrong.

Paulo


#8

I would have to see where your code is in the class and see your scope and object lifetime to see what you're trying to do....  Otherwise I'm just making an educated guess.

 

Rail


#9

Paulo, when you ask questions involving code, please show us the surrounding function and class where (1) each of your variables are defined and (2)  the code you've shown is written. In C++, it is so important to understand the scope of your variables.

Try something like this:
 

class MyClass
{
    ...
private:
    ApplicationProperties appProperties;
    ...
};

MyClass::MyClass()
{
    ...
    PropertiesFile::Options options; 
    options.applicationName = ProjectInfo::projectName; 
    options.folderName = ProjectInfo::projectName; 
    options.filenameSuffix = "settings"; 
    options.osxLibrarySubFolder = "Application Support"; 
    appProperties.setStorageParameters(options);
    ...
}

void MyClass::setTerminalType(int terminalType)
{
    appProperties.getUserSettings()->setValue("TerminalType", var(terminalType));    
}

int MyClass::getTerminalType()
{
    return appProperties.getUserSettings()->getIntValue ("TerminalType", 0);
}

Suggestion #1: Make appProperties a class member variable. This variable must exist as long as you want to access the PropertiesFile* that it manages. Once appProperties falls out of scope, you can't use the PropertiesFile pointer that getUserSettings() returned. Which brings me to....

Suggestion #2: Don't save the pointer returned from getUserSettings() for very long. The problem with storing it is that (1) once appProperties goes out of scope, it is no longer valid (this is a correctness issue), and (2) now you have two things to keep track of instead of just one (this is a maintenance issue).

If you need to access a lot of settings, you could do this:

void MyClass::resetToDefaultProperties()
{
    PropertiesFile* const props = appProperties.getUserSettings();

    props->setValue("TerminalType", var(0));
    props->setValue(...);
    props->setValue(...);
    props->setValue(...);
    ...    
} // <- at this point, props falls safely out of scope,
  // but appProperties is still valid so you can still call
  // getUserSettings() and it will return a valid pointer

In other words, don't save props in a class member variable, but it's okay to use it as a local variable for easy access.

Hopefully you can see how important it is to understand the scope of your variables. This is why we need to see where your code is in the class, just as Rail mentioned.


#10

Hi Matty,

 

thank you for your suggestion, i've made a try with it and still has a leak.

I know that the leak is on this function and related with props.

Very strange indeed.

Should i do anything on ~MyClass ?

Paulo


#11
Should i do anything on ~MyClass ?

No, not for appProperties. I've tested my technique and it works without leaks.

Do yourself a favor and spend 15 minutes and create a new project using Introjucer. Make a component with a few buttons and a TextEditor to test reading/saving a single value using the ApplicationProperties class. Follow the example I've given above.

If after those 15 minutes you haven't figured it out, post more code. You are doing something else that you are not showing us.

I know that the leak is on this function and related with props.

Finding memory leaks can be tricky. It might not be where you are assuming it is.

Don't forget to post more code.


#12

Hi Matty,

you are totally right, it worked well and smoothly. My mistake is that i had a function to check the licence of the software and this was using two String variables that were not used.

I deleted both and now it as no leaks.

Indeed to solve the leaks problem is demanding and i need to learn more about this and how to solve them.

You help was great and very important.

Also hope that your solution can be helpfull to others that may find the same problem (hope i am not the only rookie here ! hehe).

Paulo


#13

Dear Matty,

sorry to put more questions, but now i have a new situation that i don't know how to solve.

I've loaded a component that is my login component on a dialog window, without any problem:

String m;
m << "";
DialogWindow::LaunchOptions options;
Label* label = new Label();
label->setText(m, dontSendNotification);
label->setColour(Label::textColourId, Colours::darkgrey);
options.content.setOwned(label);
Rectangle<int> area(0, 0, 378, 407);
options.content->setSize(area.getWidth(), area.getHeight());
options.dialogTitle = "Login Window";
options.dialogBackgroundColour = Colours::darkgrey;
options.componentToCentreAround;
options.escapeKeyTriggersCloseButton = true;
options.useNativeTitleBar = false;
options.resizable = false;

DialogWindow* dw = options.launchAsync();
dw->setContentOwned(showLoginPage(), true);
dw->setTitleBarHeight(0);
dw->setVisible(true);
dw->centreWithSize(378, 407);

but now, when i press the close button on my login component, the component is closed but my dialog keeps open.

How do i close the dialog from my component that is inside the dialog window ?

Thanks,

Paulo


#14

now i have a new situation

New problem -> new thread. It is good forum etiquette to make sure you don't post new problems on an old thread (even if you are the original poster). If you have a new problem, please start a new thread (which I see you have already done). Since you have already started a thread for this new problem, there is no need to bring it up here.


#15

You are right