QT: Memory Issue. Can't access a Class "[SOLVED]"
-
There is no error, a empty/null string is probably being printed. push button 1 cause my class to
print its values. Here is what the output looks like:/clicked button1/
"INPUT1"Confirming Name
"INPUT1"
/clicked button2/Confirming Name
""
-
Hi,
To add to my fellow programmers, each time you call setPlayer your are creating a new board, so you have a memory leak and are "losing" one player each time.
Also, if you call on_pushButton_2_clicked first, your application will crash since you have no board yet
-
SGaist you are correct, but this is a test run, and that button would not be available till after button 1 i s clicked. My question is how i would fix this issue if a memory leak is indeed the problem. I'm trying to dynamically instantiate the class depending on user input. First the user sets the number through a combo box, then he presses button 1. However, in this example, i arbitrarily set the number of players to 2 to test.
I don't think I'm losing any single players, i'm just losing the entire board, which includes all the players and other objects inside. Thats why button 1 will be delete once it has finished its goal of instantiating board.
-
Is line 31 above the only place where a new board is constructed? Or could there be another one being created someplace else within your code?
Incidentally, with the code as written, each click of button 1 will create a new board object and leave the old one sitting out there orphaned.
There's got to be a logic error somewhere. It's not a Qt issue, that I'm sure of.
-
Line 31 is indeed the only line that will be used, and only once. I will disabled it afterwards, but for the sake of clarity, and to make sure nothing gets orphaned, it is left enabled.
-
Hi,
Try these tricks to help pinpoint the issue:
- Add some debug output in your Board constructor and destructor. This will help double-check that only 1 board is ever created, and that it doesn't get destroyed,
- In confirmName(), print the Board's address too, and check that it never changes:
@qDebug() << this->board;@
What outputs do you get?
[quote]
@
Player ** tmp_player = this->board->getPlayer();
std::string tmp_string = tmp_player[0]->getName();[
@
[/quote]I presume getPlayer() returns an array of Players? I recommend:- Renaming the function to getPlayers() (plural) for clarity
- Returning std::vector<Player*> for safety
Then, print tmp_player.size()
-
Unfortunately, I started this project completely fresh to C++ and went the array route. I would need to go back and change everything to vector, i recon that might be the problem, but it worked fine without QT and gui, so it might not be either. I'll be trying to modify it to vector in the meantime.
Also, yes, constructor for board is called once and never deconstructed.
-
[quote author="ath001" date="1395440315"]Unfortunately, I started this project completely fresh to C++ and went the array route. I would need to go back and change everything to vector, i recon that might be the problem, but it worked fine without QT and gui, so it might not be either. I’ll be trying to modify it to vector in the meantime.[/quote]That's OK. It's probably better to investigate further before rewriting large chunks of your code (which might introduce other bugs).
Memory bugs are more common in programs that do lots of manual pointer handling, which is why I recommended using std::vector. There could be a hidden bug in your Board (or Player, or other classes) that didn't cause problems in console mode. However, adding the GUI dramatically changes your memory layout, which could bring out previously-hidden bugs.
Do you have access to a Linux machine? If so, run your console app through "Valgrind":http://valgrind.org/ and see if it finds any issues.
[quote author="ath001" date="1395440315"]Also, yes, constructor for board is called once and never deconstructed.[/quote]Just to clarify: Is that what you think is happening, or is that what your app output tells you? (Ideally, they should be the same thing. But they might not be).
Also, what about the Board address -- does it change during one run? (See my previous post forhow to print the address)
-
I don't have a linux machine , i'm programming on macOS.
The constructor is called once and the deconstructor print statement were never called.
I printed the address from when the board is created in button 1, and then again once i clicked button 2, they have the same address.
-
[quote author="ath001" date="1395446699"]I don't have a linux machine , i'm programming on macOS.[/quote]I just learnt that Valgrind works on Mac too: http://valgrind.org/info/platforms.html Give it a try.
[quote]The constructor is called once and the deconstructor print statement were never called.
I printed the address from when the board is created in button 1, and then again once i clicked button 2, they have the same address. [/quote]As far as I can see, your MainWindow code is correct. I suspect the bug is in Board.
-
Okay, i install valgrind, and ran the console app through, it doesn't have any major failures and work as it should but i get a ton of these messages using :
valgrind --leak-check=full -v ./your_program
messages:
==32061== Invalid read of size 8
==32061== at 0x100014D99: RivalTowerTax::landOn(Player&) (in ./a.out)
==32061== by 0x100011E70: FreeParking::landOn(Player&) (in ./a.out)
==32061== by 0x100012B07: main (in ./a.out)
==32061== Address 0x104831520 is not stack'd, malloc'd or (recently) free'dLEAK SUMMARY:
==32084== definitely lost: 10,920 bytes in 56 blocks
==32084== indirectly lost: 5,584 bytes in 61 blocks
==32084== possibly lost: 4,829 bytes in 56 blocks
==32084== still reachable: 52,341 bytes in 278 blocks
==32084== suppressed: 0 bytes in 0 blocks
==32084== Reachable blocks (those to which a pointer was found) are not shown.
==32084== To see them, rerun with: --leak-check=full --show-reachable=yes
==32084==
==32084== ERROR SUMMARY: 1055 errors from 89 contexts (suppressed: 0 from 0)It looks pretty bad, the board runs as it should but this seems like an overwhelming amount of memory loss
-
You're making good progress. :)
Your memory leaks aren't critical at this point -- it's only in kilobytes, so your system can endure it without any noticeable effects (but it should be fixed eventually).
However, you should fix the error below ASAP:
[quote author="ath001" date="1395460591"]messages:
==32061== Invalid read of size 8
==32061== at 0x100014D99: RivalTowerTax::landOn(Player&) (in ./a.out)
==32061== by 0x100011E70: FreeParking::landOn(Player&) (in ./a.out)
==32061== by 0x100012B07: main (in ./a.out)
==32061== Address 0x104831520 is not stack'd, malloc'd or (recently) free'd[/quote]See http://valgrind.org/docs/manual/mc-manual.html#mc-manual.badrwYour program is trying to do an illegal read, so it will get garbage data. If it does an illegal write, then you might end up with memory corruption. Errors like these can easily cause board->getPlayer()[ 0]->getName() to not return the correct values.
Follow the "quick-start guide":http://valgrind.org/docs/manual/quick-start.html and see if you can get Valgrind to tell you exactly where in your source code the errors occur.
-
I mean its a good shot, but i believe theres is a hinge to overcome:
==32270== WARNING: Support on MacOS 10.8 is experimental and mostly broken.
==32270== WARNING: Expect incorrect results, assertions and crashes.
==32270== WARNING: In particular, Memcheck on 32-bit programs will fail to
==32270== WARNING: detect any errors associated with heap-allocated data.
==32270==It might not accurately represent my code at all.
-
Thanks for the help JKSH, I appreciate it, i converted it to vectors, and it worked like a charm.
-
Glad I could help :) Please edit your original post and add "[SOLVED]" to the title.
All the best with your project!
-
Glad you got it working!