Overclock.net › Forums › Software, Programming and Coding › Coding and Programming › [C++] Allocating memory to a passed pointer from inside a function [resolved]
New Posts  All Forums:Forum Nav:

[C++] Allocating memory to a passed pointer from inside a function [resolved]

post #1 of 6
Thread Starter 
For one of my courses, we're building a translator from a DSL to C++. We've completed our scanner, but I'm going back to clean up some duplicated code.
The scanner builds a linked list, where each node is a token from the DSL. tokenType is just an enum of our types.

Here's the function I'm trying to build:
Code:
void handleNewToken(tokenType tt, std::string lexeme, int &headFound, Token * head) {
  if (!headFound) {
    head = new Token(tt, lexeme);
    headFound = 1;
  } else {
    if (!head->next) {
      head->next = new Token(tt, lexeme);
    } else {
      Token * end = findLastToken(head);
      end->next = new Token(tt, lexeme);
    }
  }
}

The logic is basically: If we haven't matched any tokens yet (i.e. found the head), set it; else, if we haven't found the second token, make it, otherwise find the last token in the list (i.e. the tail), and then append there.

Here's findLastToken and the context in which handleNewToken is called, though these shouldn't matter for my issue. Code (Click to show)
Code:
Token * findLastToken(Token * head) {
  if (!head->next) return head;
  Token * n = head->next;
  while(n->next)
    n = n->next;
  return n;
}

Token * scan (const char * text) {
  ...
  Token * head;
  int headFound = 0;
  ...
  handleNewToken(..., headFound, head);
}

The trouble right now is that the first handleNewToken runs, it of course goes down to line 3 and makes a new Token for head. But, I'm guessing that only happens in the scope of the function. I verified in GDB that as soon as handleNewToken exits, the original head that was passed in is still not instantiated. I think I understand why it's happening, I just don't know how to fix it.

Basically, my question is, how do I allocate memory (new) on a pointer outside of the function?
post #2 of 6
Code:
Token *handleNewToken( const Token *head )
{
        /* Removed your code to show the basics */
        if ( head == nullptr )
                return new Token();

        return head->Next; /* or whatever... */
};

Quite simply, you pass the current Token (head) in as a const, and then return the new (or next) object, instead of trying to do pointer magic. Make sure to delete your objects smile.gif

If you still don't want to do that, you can pass in a double pointer:
Code:
void handleNewToken( Token **head )
{
        if ( *head == nullptr )
                *head = new Token;
}
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
post #3 of 6
Thread Starter 
Quote:
Originally Posted by tompsonn View Post

snip

Thanks tompsonn, you're the man.

I thought about just returning a pointer (seems like this is the better way), but then I have trouble handling the case of whether I'm returning a pointer to the head or a new tail. In this case, handling them separately works better.

A slightly unrelated question, what's the best way to handle checking for an uninitialized pointer? Right now, I do the following:
Code:
Token * scan (...) {
  /* some code */
  Token * head;
  int headFound = 0;
 /* more code */
}

I just check the integer value and set it if necessary, which is clunky. Would it be best practice to do this instead? Something else?
Code:
  Token * head = null;
  if (!head) {
     ...
post #4 of 6
Quote:
Originally Posted by EfemaN View Post

Thanks tompsonn, you're the man.

I thought about just returning a pointer (seems like this is the better way), but then I have trouble handling the case of whether I'm returning a pointer to the head or a new tail. In this case, handling them separately works better.

A slightly unrelated question, what's the best way to handle checking for an uninitialized pointer? Right now, I do the following:
Code:
Token * scan (...) {
  /* some code */
  Token * head;
  int headFound = 0;
 /* more code */
}

I just check the integer value and set it if necessary, which is clunky. Would it be best practice to do this instead? Something else?
Code:
  Token * head = null;
  if (!head) {
     ...

Ah this question...

Well I can tell you its definitely not a good idea to check a separate integer. What if someone passes in TRUE for that argument but gives a null pointer? Then you're stuck wondering why your app is segfaulting!

You must ALWAYS initialize your pointers. Now, because of this reason, it makes things simpler and sane to check for invalid pointers. Commonly, NULL is used for initialization. C++11 has nullptr, which is what I use and avoids a few issues. But if you make sure NULL is defined as zero, you can initialize your pointers to NULL and use if ( ptr ). You may be tempted to check for NULL, i.e. if ( ptr != NULL ), but the NULL macro (just like TRUE and FALSE) should not be used except as an assignment rvalue. Let the language do the proper handling, as in if ( ptr ).

If you're using C++11, the preferred way is nullptr, which you can see from my code.

Be careful with pointers to pointers, however. You must check to make sure the first pointer is valid before trying to dereference the pointer it points to. You'll notice there's a subtle bug in my code where I don't check to make sure the first pointer is valid before checking if the pointer to which it points is NULL.

Because I'm from C, I used a double pointer. You can also pass a reference to a pointer in C++ if you feel more comfortable with that.
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
post #5 of 6
Thread Starter 
Quote:
Originally Posted by tompsonn View Post

*snip*

Great! Just what I was looking for. Pointer-reference is also something new to me; I used that instead since it makes one less dereference in code.

I could probably use C++11, but there's always the chance that something changes during grading and it doesn't use that flag for compilation. At least I know it exists.

Thanks again tompsonn!
post #6 of 6
Quote:
Originally Posted by EfemaN View Post

Great! Just what I was looking for. Pointer-reference is also something new to me; I used that instead since it makes one less dereference in code.

I could probably use C++11, but there's always the chance that something changes during grading and it doesn't use that flag for compilation. At least I know it exists.

Thanks again tompsonn!

When you think about it, pointers are nothing more than a platform-width integer (e.g. 32 or 64-bit) with a virtual memory address as their value (nowadays). So in C++ the reference to a pointer is really the same as a reference to say, any other integer - and by the same logic, you could also *try* to dereference any other integer by treating it as a pointer (which, of course, wouldn't work unless you know beforehand that something actually lives there).

The reference to a pointer is probably actually preferred amongst the C++ crowd anyway smile.gif

Indeed, wasn't really a push for you to use C++11, more of a "here's what you need to do if you are using C++11"

Enjoy!
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  hide details  
Reply
Ol' Sandy
(28 items)
 
"Zeus"
(12 items)
 
Elite Preview
(6 items)
 
CPUMotherboardGraphicsRAM
Intel Xeon E3-1230v3 Gigabyte GA-Z97X-UD5H-BK MSI Gaming GTX 980 Kingston 32GB (4x8) 
Hard DriveHard DriveHard DriveHard Drive
Plextor PX-256M5S 256GB Samsung EVO 1TB Hitachi HDS721010CLA332 Hitachi HDS723020BLA642 
Hard DriveHard DriveHard DriveOptical Drive
Hitachi HDS723020BLA642 Hitachi HUA722010CLA330 WDC WD10EARS-00Z5B1 TSSTcorp CDDVDW SH-S223B 
CoolingCoolingOSMonitor
Phanteks PH-TC14PE with TY-140's Lamptron FCv5 (x2) Windows 8 Pro 64-bit Dell U2412M 
MonitorMonitorMonitorKeyboard
Dell U2412M Dell U2212HM Dell U2713HM Topre Realforce 87UB | Ducky DK9087 G2 Pro 
PowerCaseMouseMouse Pad
Corsair AX-750 Corsair Obsidian 650D Logitech G700 XTRAC Ripper XXL 
AudioAudioAudioAudio
Beyerdynamic DT-770 Pro 250ohm Schiit Bifrost DAC Schiit Asgard 2 HiVi Swan M50W 2.1 
CPUMotherboardRAMHard Drive
Intel Xeon E5-2620 Super Micro X9SRL-F-B 128GB 1333MHz LSI 9271-8i 
OSPowerCase
VMware ESXi 5.5 SeaSonic SS-400FL2 Fractal Define R3 
CPUMotherboardGraphicsRAM
Intel Core i5-3437U HP EliteBook Folio 9470m  Intel HD Graphics 4000  16GB DDR3 SDRAM 
Hard DriveOS
256GB SSD Windows 10 Insider Preview 
  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 › [C++] Allocating memory to a passed pointer from inside a function [resolved]