Card Game - Linked listing problem

Problem description:
Creating a new deck changes the properties of other decks.

Environment
Google Chrome/PC/Windows 10 Home
Consistently reproducable
C++

Link
https://replit.com/@ChristopherSebr/Game-Card?v=1

Expected behavior:
Creating /editing/printing a deck should only affect the focused deck.

Actual behavior:
Creating a second deck either

  1. Sets the first deck’s headPtr to the second deck’s headPtr
  2. Makes the first deck print the second deck

Creating a third deck ends the program
Error: “free(): double free detected in tcache 2”
“signal: aborted (core dumped)”

Steps to reproduce:

  1. Set all deck*.txt files to just have a dash “-”
  2. Run the program
  3. Enter 3 for deck lobby
  4. Enter 1 to create a new deck, name the deck
  5. Enter 3 to edit deck1
  6. Follow in-program instructions to add a few cards
  7. Enter 3, Enter 1, this will print deck1
  8. Enter 4 for deck lobby
  9. Enter 1 to create a new deck
  10. Add less cards to this than deck1
  • Test 1
  1. Enter 3, Enter 2
  2. Notice how this accepts there are no cards, and prints “empty deck”
  3. Enter 4, Enter 3, Enter 1
  4. Notice how this tries to print deck1’s card amount but tries to print deck2
  • Test 2
  1. Run the program
  2. Create a third deck
  3. Try to edit deck3

Also, you can edit the decks by editing the deck*.txt files

image

This would be a bug with your program, not Replit.

2 Likes

Make sure you’re not freeing memory that you already freed (that would indicate that you have a use-after-free vulnerability). Could you run your program with gdb ./main-debug, reproduce the bug, type bt at the gdb prompt, and send the backtrace so we can help you solve your problem?

1 Like

I forked your repl and ran your program, here’s the backtrace I got.

~/Game-Card-fork-for-Ask-debug$ gdb ./main -ex run -ex bt -ex kill -ex quit|cat
GNU gdb (GDB) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...
Starting program: /home/runner/Game-Card-fork-for-Ask-debug/main 
warning: Error disabling address space randomization: Operation not permitted
free(): double free detected in tcache 2

Program received signal SIGABRT, Aborted.
0x00007f8d07eeabaa in raise ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#0  0x00007f8d07eeabaa in raise ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#1  0x00007f8d07ed5523 in abort ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#2  0x00007f8d07f2b2e8 in __libc_message ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#3  0x00007f8d07f32b0a in malloc_printerr ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#4  0x00007f8d07f34d66 in _int_free ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#5  0x00007f8d07f37a94 in free ()
   from /nix/store/9bh3986bpragfjmr32gay8p95k91q4gy-glibc-2.33-47/lib/libc.so.6
#6  0x000000000040922c in __gnu_cxx::new_allocator<char>::deallocate (
    this=0xfb5aa0, 
    __p=0x2 <error: Cannot access memory at address 0x2>, 
    __t=<optimized out>)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/ext/new_allocator.h:133
#7  std::allocator_traits<std::allocator<char> >::deallocate (__a=..., 
    __p=0x2 <error: Cannot access memory at address 0x2>, 
    __n=<optimized out>)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/alloc_traits.h:492
#8  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_destroy (this=0xfb5aa0, __size=<optimized out>)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/basic_string.h:237
#9  std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_dispose (this=0xfb5aa0)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/basic_string.h:232
#10 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string (this=0xfb5aa0)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/basic_string.h:658
#11 Card::~Card (this=0xfb5a00) at ./card.h:32
#12 0x0000000000439b3a in CardNode::~CardNode (this=0xfb5a00)
    at ./cardNode.h:20
#13 Deck::~Deck (this=0xfb67e0) at ./deck.h:25
#14 std::_Destroy<Deck> (__pointer=0xfb67e0)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/stl_construct.h:140
#15 std::_Destroy_aux<false>::__destroy<Deck*> (__first=0xfb67e0, 
    __last=0xfb6810)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/stl_construct.h:152
#16 std::_Destroy<Deck*> (__first=0xfb67b0, __last=0xfb6810)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/stl_construct.h:184
#17 std::_Destroy<Deck*, Deck> (__first=0xfb67b0, __last=0xfb6810)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/alloc_traits.h:738
#18 std::vector<Deck, std::allocator<Deck> >::_M_realloc_insert<Deck const&> (this=this@entry=0x7fffda1fdae0, __position=__position@entry=..., 
    __args=...)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/vector.tcc:498
#19 0x00000000004398f7 in std::vector<Deck, std::allocator<Deck> >::push_back (this=this@entry=0x7fffda1fdae0, __x=...)
    at /nix/store/dlni53myj53kx20pi4yhm7p68lw17b07-gcc-10.3.0/include/c++/10.3.0/bits/stl_vector.h:1198
#20 0x0000000000433f56 in setDeckCase (CDB=..., deckCase=...)
    at ./cardDB.cpp:2649
#21 0x0000000000409cfb in main () at ./cardGame.cpp:27
Kill the program being debugged? (y or n) y
[Inferior 1 (process 894) killed]
~/Game-Card-fork-for-Ask-debug$ 

Thanks for the help. I found that I was uselessly deleting the Deck’s head pointer in the Deck destructor. I’ll be more carefull as to where I post my topics.