Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Erasing a map entry containing a pointer
New Posts  All Forums:Forum Nav:

Erasing a map entry containing a pointer

post #1 of 8
Thread Starter 
Ok. I have a program I'm writing that uses maps. The first value of the map is a string, and the second is a pointer to a class. I have to write a function that will search my map for a certain key and then erase that entry and delete the pointer. Problem is, I'm not really sure how to do this. If I erase my map entry first, can I still call delete on that pointer? Any help would be greatly appreciated.

Code:
int Code_Processor::Delete_User(string username)
{

    map <string, User *>::iterator nit;

    for(nit = Names.begin(); nit != Names.end(); nit++){
        if(nit->first == username){
            Names.erase(nit++);
        }else if(nit++ == Names.end()){
            return -1;
        }else;
    }

    for(nit = Phones.begin(); nit != Phones.end(); nit++){
        if(nit->second->username == username){
            Phones.erase(nit++);
            delete nit->second;
        }
    }

    return 0;
}
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
post #2 of 8
You can't use something you've just erased! That's like expecting your files to still be on your hard drive after you (long) format it. So delete the pointer first.
Underground
(14 items)
 
  
CPUMotherboardGraphicsRAM
Core i7 920 C0 ASUS P6T6 WS Revolution GTX 460 TR3X6G1600C8D 
Hard DriveOptical DriveCoolingOS
WD1001FALS SAMSUNG SH-S223F 22X DVD MULTI Corsair H50 Fedora 16 KDE x86_64 
MonitorKeyboardPowerCase
HP w19b Microsoft Comfort Curve Corsair CX600 Thermaltake Armor VA8003BWS 
MouseMouse Pad
Razer DeathAdder Black 
  hide details  
Reply
Underground
(14 items)
 
  
CPUMotherboardGraphicsRAM
Core i7 920 C0 ASUS P6T6 WS Revolution GTX 460 TR3X6G1600C8D 
Hard DriveOptical DriveCoolingOS
WD1001FALS SAMSUNG SH-S223F 22X DVD MULTI Corsair H50 Fedora 16 KDE x86_64 
MonitorKeyboardPowerCase
HP w19b Microsoft Comfort Curve Corsair CX600 Thermaltake Armor VA8003BWS 
MouseMouse Pad
Razer DeathAdder Black 
  hide details  
Reply
post #3 of 8
Thread Starter 
Quote:
Originally Posted by superhead91 View Post
Code:
int Code_Processor::Delete_User(string username)
{

    map <string, User *>::iterator nit;

    for(nit = Names.begin(); nit != Names.end(); nit++){
        if(nit->first == username){
            Names.erase(nit++);
        }else if(nit++ == Names.end()){
            return -1;
        }else;
    }

    for(nit = Phones.begin(); nit != Phones.end(); nit++){
        if(nit->second->username == username){
            Phones.erase(nit++);
            delete nit->second;
        }
    }

    return 0;
}
So if I switch the two bold lines it should work?
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
post #4 of 8
Quote:
Originally Posted by superhead91 View Post
So if I switch the two bold lines it should work?
One would think so.
Underground
(14 items)
 
  
CPUMotherboardGraphicsRAM
Core i7 920 C0 ASUS P6T6 WS Revolution GTX 460 TR3X6G1600C8D 
Hard DriveOptical DriveCoolingOS
WD1001FALS SAMSUNG SH-S223F 22X DVD MULTI Corsair H50 Fedora 16 KDE x86_64 
MonitorKeyboardPowerCase
HP w19b Microsoft Comfort Curve Corsair CX600 Thermaltake Armor VA8003BWS 
MouseMouse Pad
Razer DeathAdder Black 
  hide details  
Reply
Underground
(14 items)
 
  
CPUMotherboardGraphicsRAM
Core i7 920 C0 ASUS P6T6 WS Revolution GTX 460 TR3X6G1600C8D 
Hard DriveOptical DriveCoolingOS
WD1001FALS SAMSUNG SH-S223F 22X DVD MULTI Corsair H50 Fedora 16 KDE x86_64 
MonitorKeyboardPowerCase
HP w19b Microsoft Comfort Curve Corsair CX600 Thermaltake Armor VA8003BWS 
MouseMouse Pad
Razer DeathAdder Black 
  hide details  
Reply
post #5 of 8
Quote:
Originally Posted by superhead91 View Post
Ok. I have a program I'm writing that uses maps. The first value of the map is a string, and the second is a pointer to a class. I have to write a function that will search my map for a certain key and then erase that entry and delete the pointer. Problem is, I'm not really sure how to do this. If I erase my map entry first, can I still call delete on that pointer? Any help would be greatly appreciated.

Code:
int Code_Processor::Delete_User(string username)
{

    map <string, User *>::iterator nit;

    for(nit = Names.begin(); nit != Names.end(); nit++){
        if(nit->first == username){
            Names.erase(nit++);
        }else if(nit++ == Names.end()){
            return -1;
        }else;
    }

    for(nit = Phones.begin(); nit != Phones.end(); nit++){
        if(nit->second->username == username){
            Phones.erase(nit++);
            delete nit->second;
        }
    }

    return 0;
}
So 'Names' and 'Phones' are two different containers, I'm assuming they're of the same type as you're using the iterator from the first for loop in the second for loop.

Here are some questions/comments:
1.) Why have 'Names' and 'Phones' as two separate containers?
2.) If you have a map, and your checking against it's key then why are you looping through it? You can simply use map::find()
3.) Your 'else if' in your first loop is making things very confusing, your for loop is already iterating your iterator and checking against .end(). If you 'return 1' in that loop you'll never make it to the second loop as well. And what's with the empty else at the end? Does that compile? I've never seen syntax like that.
4.) As this isn't a multi-map, each key in the map is unique, so once you found a match you could break so that you're not needlessly looping afterwards.
5.) If the string passed into this function was passed as a const reference it would prevent a copying of the string, which is more efficient (but unrelated to your question).
6.) When you delete your pointer you might consider checking it against NULL. This is optional, if you know for certain it will not be null, then the delete shouldn't cause an access violation, but I tend to use a macro or function that always checks null before a delete.
7.) If somehow the username existed in Names but not in Phones you will have removed the entry from Names without deleting the pointer to the class, and the pointer could then be lost forever (memory leak).

Here's my attempt (bear in mind I have no tried to compile this or anything):
Code:
int Code_Processor::Delete_User( const string& username )
{
    std::map<string, User*>::iterator nit = Names.find(username);

    // We found a match
    if ( nit != Names.end() )
    {
         if ( nit->second != NULL )
         {
               delete nit->second;
               nit->second = NULL;   // We set it to NULL so we can check if it was deleted later on
         }

         Names.erase(nit);
    }

    nit = Phones.find(username);

    if ( nit != Phones.end() )
    {
         // Could been set to NULL if this pointer was erased while checking 'Names'.
         if ( nit->second != NULL )
         {
               delete nit->second;
               nit->second = NULL;
         }

         Phones.erase(nit);
    }

    return 0; // I'm not sure what the return value for this function is meant to do, so I'm just using what you had.
}

Edited by lordikon - 4/11/11 at 7:18am
Foldatron
(17 items)
 
Mat
(10 items)
 
Work iMac
(9 items)
 
CPUMotherboardGraphicsGraphics
i7 950 EVGA x58 3-way SLI EVGA GTX 660ti GTX 275 
RAMHard DriveHard DriveHard Drive
3x2GB Corsair Dominator DDR3-1600 80GB Intel X25-M SSD 2TB WD Black 150GB WD Raptor 
Hard DriveOSMonitorKeyboard
2x 150GB WD V-raptor in RAID0 Win7 Home 64-bit OEM 55" LED 120hz 1080p Vizio MS Natural Ergonomic Keyboard 4000 
PowerCase
750W PC P&C Silencer CoolerMaster 690 
CPUGraphicsRAMHard Drive
Intel Core i5 2500S AMD 6770M 8GB (2x4GB) at 1333Mhz 1TB, 7200 rpm 
Optical DriveOSMonitorKeyboard
LG 8X Dual-Layer "SuperDrive" OS X Lion 27" iMac screen Mac wireless keyboard 
Mouse
Mac wireless mouse 
CPUGraphicsRAMHard Drive
i7-2600K AMD 6970M 1GB 16GB PC3-10600 DDR3 1TB 7200rpm 
Hard DriveOptical DriveOSMonitor
256GB SSD 8x DL "SuperDrive" OS X 10.7 Lion 27" 2560x1440 iMac display 
Monitor
27" Apple thunderbolt display 
  hide details  
Reply
Foldatron
(17 items)
 
Mat
(10 items)
 
Work iMac
(9 items)
 
CPUMotherboardGraphicsGraphics
i7 950 EVGA x58 3-way SLI EVGA GTX 660ti GTX 275 
RAMHard DriveHard DriveHard Drive
3x2GB Corsair Dominator DDR3-1600 80GB Intel X25-M SSD 2TB WD Black 150GB WD Raptor 
Hard DriveOSMonitorKeyboard
2x 150GB WD V-raptor in RAID0 Win7 Home 64-bit OEM 55" LED 120hz 1080p Vizio MS Natural Ergonomic Keyboard 4000 
PowerCase
750W PC P&C Silencer CoolerMaster 690 
CPUGraphicsRAMHard Drive
Intel Core i5 2500S AMD 6770M 8GB (2x4GB) at 1333Mhz 1TB, 7200 rpm 
Optical DriveOSMonitorKeyboard
LG 8X Dual-Layer "SuperDrive" OS X Lion 27" iMac screen Mac wireless keyboard 
Mouse
Mac wireless mouse 
CPUGraphicsRAMHard Drive
i7-2600K AMD 6970M 1GB 16GB PC3-10600 DDR3 1TB 7200rpm 
Hard DriveOptical DriveOSMonitor
256GB SSD 8x DL "SuperDrive" OS X 10.7 Lion 27" 2560x1440 iMac display 
Monitor
27" Apple thunderbolt display 
  hide details  
Reply
post #6 of 8
Thread Starter 
Yeah. I got rid of the if else statement and used map::find() pretty much like you did. I've already turned it in but something is still nagging me. If I create classes by making a pointer and then setting that pointer to a new instance of that class, will deleting the pointer delete the class as well, or will it just delete the pointer and then leave the contents of the class in memory with no way to access it?
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
post #7 of 8
Quote:
Originally Posted by superhead91 View Post
Yeah. I got rid of the if else statement and used map::find() pretty much like you did. I've already turned it in but something is still nagging me. If I create classes by making a pointer and then setting that pointer to a new instance of that class, will deleting the pointer delete the class as well, or will it just delete the pointer and then leave the contents of the class in memory with no way to access it?
If you call delete on a pointer, it will delete what the pointer is pointing to.

That gets me thinking, my original code missed something. After calling delete, set your pointer to NULL. I'll change my original post to reflect that, so others reading this thread get the right impression.

Anyway

Code:
// Creates a new MyClass and gives me a pointer to it
MyClass* pClass = new MyClass();

// Deletes the MyClass pointed to by pClass.
delete pClass;

// Lets us check pClass later on for NULL so we don't try and delete it again.
pClass = NULL;
Foldatron
(17 items)
 
Mat
(10 items)
 
Work iMac
(9 items)
 
CPUMotherboardGraphicsGraphics
i7 950 EVGA x58 3-way SLI EVGA GTX 660ti GTX 275 
RAMHard DriveHard DriveHard Drive
3x2GB Corsair Dominator DDR3-1600 80GB Intel X25-M SSD 2TB WD Black 150GB WD Raptor 
Hard DriveOSMonitorKeyboard
2x 150GB WD V-raptor in RAID0 Win7 Home 64-bit OEM 55" LED 120hz 1080p Vizio MS Natural Ergonomic Keyboard 4000 
PowerCase
750W PC P&C Silencer CoolerMaster 690 
CPUGraphicsRAMHard Drive
Intel Core i5 2500S AMD 6770M 8GB (2x4GB) at 1333Mhz 1TB, 7200 rpm 
Optical DriveOSMonitorKeyboard
LG 8X Dual-Layer "SuperDrive" OS X Lion 27" iMac screen Mac wireless keyboard 
Mouse
Mac wireless mouse 
CPUGraphicsRAMHard Drive
i7-2600K AMD 6970M 1GB 16GB PC3-10600 DDR3 1TB 7200rpm 
Hard DriveOptical DriveOSMonitor
256GB SSD 8x DL "SuperDrive" OS X 10.7 Lion 27" 2560x1440 iMac display 
Monitor
27" Apple thunderbolt display 
  hide details  
Reply
Foldatron
(17 items)
 
Mat
(10 items)
 
Work iMac
(9 items)
 
CPUMotherboardGraphicsGraphics
i7 950 EVGA x58 3-way SLI EVGA GTX 660ti GTX 275 
RAMHard DriveHard DriveHard Drive
3x2GB Corsair Dominator DDR3-1600 80GB Intel X25-M SSD 2TB WD Black 150GB WD Raptor 
Hard DriveOSMonitorKeyboard
2x 150GB WD V-raptor in RAID0 Win7 Home 64-bit OEM 55" LED 120hz 1080p Vizio MS Natural Ergonomic Keyboard 4000 
PowerCase
750W PC P&C Silencer CoolerMaster 690 
CPUGraphicsRAMHard Drive
Intel Core i5 2500S AMD 6770M 8GB (2x4GB) at 1333Mhz 1TB, 7200 rpm 
Optical DriveOSMonitorKeyboard
LG 8X Dual-Layer "SuperDrive" OS X Lion 27" iMac screen Mac wireless keyboard 
Mouse
Mac wireless mouse 
CPUGraphicsRAMHard Drive
i7-2600K AMD 6970M 1GB 16GB PC3-10600 DDR3 1TB 7200rpm 
Hard DriveOptical DriveOSMonitor
256GB SSD 8x DL "SuperDrive" OS X 10.7 Lion 27" 2560x1440 iMac display 
Monitor
27" Apple thunderbolt display 
  hide details  
Reply
post #8 of 8
Thread Starter 
Ok. Thanks. I didn't set my pointers to null afterwards, but I will remember that for future reference.
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
Sulaco
(14 items)
 
 
MacBook Pro
(4 items)
 
CPUMotherboardGraphicsRAM
Phenom II X6 1090T Asus Crosshair IV Formula Sapphire 7950 3GB 2x2GB Mushkin Enhanced Blackline  
Hard DriveOSMonitorPower
2x150GB Velociraptor RAID 0 | 2x1TB Hitachi Windows 8 Asus VH242H OCZ ModXStream 700W 
Case
Cooler Master HAF 932 
CPUGraphicsOSMonitor
Core 2 Duo P8400 GeForce 9400M OSX Yosemite 13.3" LED-backlit 
  hide details  
Reply
New Posts  All Forums:Forum Nav:
  Return Home
  Back to Forum: Coding and Programming
Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › Erasing a map entry containing a pointer