[PLUG] C++ pointer freeing problem

Carlos Konstanski ckonstanski at pippiandcarlos.com
Mon Feb 15 17:49:29 UTC 2010


On Mon, 15 Feb 2010, Tim Wescott wrote:

> Date: Mon, 15 Feb 2010 09:31:09 -0800
> From: Tim Wescott <tim at wescottdesign.com>
> Reply-To: "General Linux/UNIX discussion and help;	civil and on-topic"
>     <plug at lists.pdxlinux.org>
> To: "General Linux/UNIX discussion and help;	civil and on-topic"
>     <plug at lists.pdxlinux.org>
> Subject: Re: [PLUG] C++ pointer freeing problem
> 
> Tony Rick wrote:
>> On Sun, Feb 14, 2010 at 3:13 PM, Carlos Konstanski <
>> ckonstanski at pippiandcarlos.com> wrote:
>>
>>
>>> On Sun, 14 Feb 2010, Tony Rick wrote:
>>>
>>> Commenting out the "if(! numericP()) {}" block circumvents the
>>> error. Therefore it seems reasonable that something in numericP() is
>>> causing the trouble. That's what led me to look at the treatment of
>>> the *char. Now I think it's corrupting rawInput().
>>>
>>> Is it bad to keep using getRawInput() directly whenever I want to read
>>> its value, instead of getting a copy into a local variable? This would
>>> cause no problems in Java, Lisp, etc, but perhaps C++ is
>>> different. I'll try changing that.
>>>
>>> I appreciate all your help thus far. It is good to know that I should
>>> not bark up the free() tree.
>>>
>>> Carlos
>>> _______________________________________________
>>> PLUG mailing list
>>> PLUG at lists.pdxlinux.org
>>> http://lists.pdxlinux.org/mailman/listinfo/plug
>>>
>>>
>>
>> The corruption may be that member function getRawInput() itself has been
>> nuked, or that member variable rawInput has been nuked, or that the  table
>> holding the info about class members has been nuked,  Since I can't see how
>> a simple reference to the variable or the function call could produce a NaN
>> to trigger the exception, I lean toward the last one, which involves an
>> index into a lookup table, if I recall my C++ Class implementation details
>> correctly.   This would mean that the corruption is way bad, caused by
>> writing memory locations gone wild, for example.
>>
>> One point about accessors (eg, get/setRawInput):  they are generally for
>> access from the 'outside world', part of the information hiding paradigm.
>> Inside a class instance, member variables are directly accessible, unless
>> you go to some extraordiary lengths to make them not so.  I would not use
>> get/setRawInput in any of the Validator methods, but the variables
>> themselves.
>>
>> const char* charSequence = rawInput.c_str();
>>
> I would take that under advisement -- sometimes you _do_ want to use a
> class's accessor functions from within the class, particularly when its
> large and complex (and maybe due to be split up) or when you know that
> you will always need the information as presented to the outside world
> and you suspect that you're going to change the internal representation.
>
> -- 
> Tim Wescott
> Wescott Design Services
> Voice: 503-631-7815
> Cell:  503-349-8432
> http://www.wescottdesign.com

I agree. Getters and setters are not just for avoiding direct access
of a member; they are for encapsulating logic that may need to be
performed every time a member is accessed. GNU GCC does a fine job of
not exposing implementation bugs when using accessors. Microsoft's
compiler has glitches.

But I did have a bug in my code. I called rawInput.size() after using
c_str(). The spec says that there is no guarantee that the temporary
buffer containing the copy of the string to which my *char points will
survive such an event. Once you call c_str(), you have to be sure to
leave the original string alone.

Yet this bug didn't affect my Microsoft problem; using an ordinary
string variable in place of a getter call is what fixed it for me
(i.e. copying the result of calling getRawInput() into a scalar
variable, and using the variable). If c_str() makes a copy of the
string into a temp buffer, why should it matter that I called a
function that returned a string, or performed a calculation that
returned a string, or did anything else that ends up being a string?
That's a transgression against functional programming style.

I am so glad that I am going through the extra work of writing my code
in Linux, and then copying it into Windows for final packaging. It is
teaching me loads about C++ whenever I see something not work that
should.

Carlos



More information about the PLUG mailing list