KIS Systems, Inc - Contract Programming for Unix/Windows/Web in C++/C#/PHP/Qt/.NET and other technologies.

KIS Technoblog

Technical ruminations from our chief codemeister – Rick Berger

Archive for December, 2006

STL Gotchas – maps

Posted by admin on 20th December 2006

Ah, the STL (C++ Standard Template Library). That viper’s nest of templates within templates, allocators within allocators, unfollowable pointers, and syntax full of arcanity.

Useful, though. Primarily because, increasingly, it comes as part of any competent C++ compiler, and it is reasonably cross-platform compatible (well, the platforms I code on, anyway.)

Maps

Maps can be a particularly useful construct – they store key-value pairs in a structure (typically a balanced b-tree) that facilitates fast ordered insertion and fast lookups.

Here’s an STL map declaration for a bunch of floats, index by strings:

   #include <map>
   #include <string>

   std::map<std::string, float> floatMap;


Not too terrible (don’t forget the ’std::’!), but everywhere you want to reference/use it, you have to specify the full templated specification. Continuing the above header declarations, for instance:

   ...
   void DoSomethingWithMap(std::map<std::string, float> &theMap);
   // pass a reference to the map in a function

That can get pretty onerous, especially if somewhere down the line you want to change one of the types. So, what I like to do is typedef the map declaration:

   #include <map>
   #include <string>
   ...
   typedef std::map<std::string, float> FloatMap;
   FloatMap floatMap
   ...
   void DoSomethingWithMap(FloatMap &theMap);

That’s makes for less typing, and you now have a type associated with the map. Another way you can do this is to subclass it:

   #include <mapgt;
   #include <string>
   ...
   class FloatMap : public std::map<std::string, float>
   {
   public:
      // override/add functions, here
   };
   ...
   // everything else works exactly the same.
   //
   FloatMap floatMap
   ...
   void DoSomethingWithMap(FloatMap &theMap);
   ...

Using the Map – the [] Operator

Now, you want to put things in the map, and get things out of the map. There is a very arcane way of doing it, declaring pairs (which is another templated structure) for each of your key-value pairs and calling the ‘insert’ function for each. Fortunately, the implementers provided a simple ‘[]‘ operator, which can be used thusly to assign:

   ...

   floatMap["pi"] = atanf(1.0f) * 4.0f; // (3.1415...)
   ...

And to use it:

   ...

   circumf = r * floatMap["pi"] * 2;

   ...

The Gotcha

All the above is straightforward, but here’s a question: what if you want to test to see if a key is in the map? Intuitively, you might do this:

   ...
   if (!floatMap["avogadro"])
       // do something

If “avogadro” is not in the map, the reference will return NULL, which we would expect. But, here’s the “gotcha”: the statement inserts the key “avogadro” with a NULL value. Sure, it will always return null (unless you set it to something), but the key now exists in the map, where the intent was to simply test if the key was there and do something else. If you were testing a whole bunch of different strings, you’d be needlessly filling up the map with keyword pairs.

So, how do we test the value? Well, the formal way goes something like this:

   ...
   using namespace std;
   // don't forget this....

   FloatMap::iterator fmIter = floatMap.find("avogadro");
   if (fmIter != floatMap.end())
      value = fmIter->second;

Kinda wordy. We can shorten it to this, remove the iterator declaration, and keep using our intuitive bracket [] operator, as follows:

   ...
   using namespace std;
   // don't forget this....

   if (floatMap.find("avogadro") != floatMap.end())
      value = floatMap["avogadro"];  (// for instance

Ah! That’s neater. And we don’t get the assignment side-effect.

Summary

The STL is useful, and it’s great that compilers are supporting it more uniformly. But it is syntactically arcane and prone to misunderstood behavior, if you’re not careful. Watch especially shortcut techniques and the use of bracket operators.

rickb

Posted in C++, standard template library, stl | No Comments »

Things MacIntosh – The Promise II

Posted by admin on 10th December 2006

The Promise, Revisited

The White MacBook had been running reasonably well, since I got it back from AppleCare. Outside of the occasional hang from the DVD player, I hadn’t had any further experiences with the Dreaded Random Shutdown Syndrome, or the Dreaded Vertical Line syndrome.

It was time to put this thing to work, and see if the multiple OS situation was feasible.

Apple provided an interesting intermediary solution – you can dual-boot Windows in a separate disk partition. Not bad, but to be able to have a web-server running in a separate machine, I need real virtualization, or I’m back to lugging around multiple machines.

VMWare, my old stalwart on Win machines wasn’t available on the Mac. But, a new company had sprung up, called “Parallels”, and, lo and behold, they did claim to work on the Mac. In fact, Apple all but endorsed them.

I downloaded the demo version, installed it and then installed an XP image, configured it enough to see the Windows boot screen and desktop come up, and promptly bought it.

Now, it’s an early version of the software, and there are a few wankiness’es about the environment, but fundamentally, it’s working. Parallels supports all of the versions of Windows, most Linux distributions, FreeBSD, and Solaris. They’ll all boot up and run, in parallel. Wankiness’es include having to reboot the guest machine to change anything, including network settings, not a true NAT implementation, and USB1.1 support only.

But, the development team is working hard and furiously on updates – the last fixed the reboot-on-network-change issue, and USB 2.0 is rumored to be in the works, as well as ability to burn CD/DVD’s, etc., etc.

The Promise: Realization

After a few weeks of configuration, I now have pushed over pretty much all of my Windows envoironment to the Parallels VM on MacIntosh. Additionally, I have two VMs of FreeBSD (a minimal version for web-serving and a full version for X-Windows/KDE testing), and more planned. With 2gb of memory, I can run up to three OS’s simultaneously. When I flip into full screen, I don’t even know I’m on a MacIntosh. But, when I want it, I have Mac available on the same platform.

It’s been a bit of a road. But it’s been worth it.

I now can carry only a single machine, if I want to. In practical terms, that’s not always feasible – I like to carry a backup on long trips, in case my primary machine fries. But, I don’t have to, especially when I go out on quickie jaunts.

I’m a happy camping developer.

rickb

Posted in Mac, MacIntosh, Parallels, VM, VMWare, Virtual Machine Software | No Comments »

Things MacIntosh – Initial Experiences

Posted by admin on 10th December 2006

The New: White MacBook

The new Intel MacBooks were out, and it was time to upgrade. So, I popped for a nice, shiny white MacBook, maxed out as much as possible with the 2ghz Intel Duo processor, 160gb hard-drive, and 2gb memory. Figured that should last for a while.

(Why, you might ask, not a MacBook Pro? Frankly, IMHO, the Pros are a lot of footprint and bulk to carry around. From the comparison specs, I couldn’t see any difference in pure processing power between the Pro and the standard Black/White MacBook. The standard configuration is a lot smaller, lighter, and thinner, although Apple could take a lesson from Toshiba and Fujitsu on making small notebooks.)

Things with the new Mac went well, initially – I put on Parallels (worth a review in it’s own right), added the development kit, and started filling it up.

Then, the unimaginable happened: as I was working, the machine just blinked off. I blinked back and tried to reboot. No, it didn’t want to reboot. I held the power button down for the extended five-second period, and it booted, albeit very reluctantly. It took a good five minutes for it to reboot.

Thinking it was just a glitch, I continued on and at the end of the session, powered the machine down. Imagine my disappointment when the machine wouldn’t boot up, normally (I had to use the long hold on the power button, again), and even more dismay when it konked out in the middle of a session, again. No warnings, no, “Hi! I need to reboot..” message accompanied by a smiley face. Nada. Just suddenly black screen.

The Dreaded Random Shutdown Syndrome

A perusal of the web revealed I wasn’t the only one having these troubles. There were reports of incidents all over the Mac forums, with the responses from Apple being vague disclaimers: “Gee, we’ve never heard of that…” type, followed up by recommendations to to a hard reset, a PRU reset, etc., etc., etc.

But, as I dug deeper, I could see there was more to the problem. There was (may still be as of this writing) a full domain dedicated to the issue (macbookrandomshutdown.com), with a lot of disgruntled folks complaining about Apple’s indifference and threatening a class-action lawsuit.

Time to call Apple. The person on the other end I talked to was extremely polite, and didn’t ask me to go through the “reset the following six things and maybe re-install your operating system” dance (ok, an exaggeration, but that’s what it feels like.) He just gave a number and sent a box, which arrived the next day. I packed the machine per instructions and sent it in.

The machine came back within a week, all clean and shiny. None of the horror stories I’d read about happened (like the hard-drive being cleaned prior to return.) The machine booted up, and seemed to work fine.

The Dreaded Vertical Lines Syndrome

All seemed well, until I booted it up one morning and was greeted by a gray screen, with slowly-filling-in vertical color-lines. No happy face, no desktop, nada. A reboot repeated the scenario.

Fine. Good thing I’d kept the box.

Another call to Apple, another courteous response, and an interesting answer: This was actually a known problem, and was resolved by … an OS upgrade. Get outta here! It certainly looked like a hardware issue, to me.

But, I followed the gentleman’s advice and installed the latest upgrade (2.4.8, at the time), and, voila! No more grey screen with vertical color-lines. After about six weeks of messing around, maybe I could get back to making this thing suit my purposes.

(Cont’d next…)

rickb

Posted in Mac, MacIntosh, Parallels, VM, VMWare, Virtual Machine Software | No Comments »

Things MacIntosh – The Promise

Posted by admin on 10th December 2006

The Promise

As a cross-platform software/web developer, I find it important to have as many platforms as feasible available on which to test/adopt various pieces of software or webpages. There’s simply no other way to guarantee cross-platform robustness than having an actual running system available.

Under normal circumstances, that means packing a lot of hardware. But, with the advent of virtual machine technology, I’ve been able to consolidate at least the Intel OS’s (various flavors of Windows/Unix) with a thing called VMWare Workstation that allows multiple OS’s to run on a single box.

This has been good, but the Apple MacIntosh has been the odd duck in the parade. It didn’t run on Intel chips, so virtualization wouldn’t work with the Mac OS.

Thus, I have had a Mac for a while. (I still have a Color Classic kicking around in my office, waiting until it becomes an ‘art collectible’, if anyone reading this is interested: I can dispose of it for a premium! (Not holding my breath – the last eBay check, they were going for something like a $160, and that’s with original manuals, box, and everything.)

The Old: Wallstreet

Anyway, for a number of years, I had a Wallstreet MacBook. The kind in the big black case with the bronze/transparent keyboard.

As it went, it was a reasonable machine – G3 processor, nice big screen, reasonable touch. But, since it wasn’t used very often, the PRU battery kept dying, which meant it wouldn’t boot, or it would throw the power management board, completely. I went through a lot of power management boards on that machine. Finally, the last time it died it failed all attempts to rescuscitate: maybe it was time for an upgrade.

Besides, now that the new Intel-based Macs were out, an interesting thought began to form in the back recesses of my mind: If Mac is going to Intel, I wondered if VMWare might not work on it. The idea of being able to run all of the major operating systems on a single platform was very tantalizing, if not flat-out mouth-drooling…

(To be cont’d…)

rickb

Posted in Mac, MacIntosh, Parallels, VM, VMWare, Virtual Machine Software | No Comments »

Pointers in C#-land – Episode II

Posted by admin on 7th December 2006

So, I’ve been a bit derelict (and busy).

Pointers, Cont’d

Let’s see – when last we left, we were discussing pointers in C#, how they’re used properly and all of that. Now, we’ll look at some improper usage.

Recall we can create a ‘fix’ block tied to a pointer, thus:

   float[] fAry;
   ...
   fix (float *pAry = fAry)
   {
      // reference (but not change) the pointer.
   }

All well and good, but, what if we do something like this?

   class AClass
   {
      private float[] fAry;

      float *GetArray()
      {
         fix (float *pAry = fAry)
         {
            return pAry;
         }
      }
   }

If little bells aren’t going off in your head, they should be. What happens when we return a pointer from a fixed block? Think local variable – when you return a local variable, it’s abandoned on the stack and no longer guaranteed to hold the value set while the function block was active (in scope.)

Well, the same thing happens to fixed pointers. They’re abandoned out of scope, and the includes a return – they’re only valid while the blocked scope is active. You can pass them down, but you can’t pass them up, because the scope is gone on return.

(This, parenthetically, is what the aforementioned system I was using was doing. Instead of taking it at face value, I should have scrutinized the pointer return more closely…)

Another Way

You could do the above the following way:

   class AClass
   {
      private float[] fAry;
      private GCHandle hAry;

      float *GetArray()
      {
         hAry = Alloc(fAry, GCHandleType.Pinned);
         float *pAry = (float *)hFloatBuf.AddrOfPinnedObject().ToPointer();
         return pAry;
      }

      void ReleaseArray()
      {
         hAry.Free();
      }
   }

The returned pointer can be used to the caller’s heart’s content.

Of course, the rub is that ReleaseArray() has to be called when the caller is done. Otherwise, the memory is pinned forever and things start slowing up, because the garbage collector has to work around the pinned block. There are a lot of things that can cause that to happen – an uncaught exception, a premature return out of an ‘if’ block or loop, or just plain forgot that was how we implemented it (my personal bane.)

So, we need something a bit safer, with no funky policy to define.

We could try something like this:

   class AClass
   {
      private float[] fAry;
      private GCHandle hAry;

      GCHandle &GetArrayHandle()
      {
         return hAry;
         // return the handle.
      }
   }

Now, the caller gets a handle, and they can pin/unpin the memory as they wish. But, what’s the point? If we’re going to give the caller control, just return a reference to the item and be done with it:

   class AClass
   {
      private float[] fAry;
      float[] FAry { get { return fAry; } }
   }

   ....

   // caller code
   AClass aClass;

   fix (float *pAry = aClass.FAry)
   {
       // reference the pointer.
   }

Or they can lock it with a GCHandle or whatever. The main thing is that the caller has declared the pointer, and in so doing, know they are responsible for it’s un-pinning/un-fixing. That keeps the pointer locking/unlocking in the same block or at least in the same context, if not scope.

rickb

Posted in .NET, CSharp, Programming | No Comments »