Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   Object/variable scope problems (Linux and Win comparison) (http://www.velocityreviews.com/forums/t744309-object-variable-scope-problems-linux-and-win-comparison.html)

Mark 02-28-2011 12:39 PM

Object/variable scope problems (Linux and Win comparison)
 
Hi all,

I am making a program which will run on Linux/Unix and Win platforms.
The Win part is completed (compiled with MinGW) and I am concentrating
now on the *NIX one.
I am trying to use standard library as much as possible, but as you
may know there are specific tasks that relies only on OS capabilities.
Basically, apart from main and various threads/child processes, the
program consists of a few classes.
Let's consider two of them and call them CControlClass and
CLoggerClass.

The implementation is very similar both in Win and *NIX.
CControlClass incorporates CLoggerClass this way.
*LoggerObj is declared as private member of CControlClass.
(CLoggerClass *LoggerObj)

CControlClass::CControlClass()
{ readConfFile("somefile.conf"); }

int CControlClass::readConfFile(const char * somefile){
//do some parsing
LoggerObj=new CLoggerClass("some_log_file.log");
LoggerObj->writeLog(some_const_int,some_char_array_or_string stream)
}

int CControlClass::functionOne()
{
//something
LoggerObj->writeLog(...,...)
}
//main.cpp
int main(int argc, char** argv)
{
CControlClass *ControlObj=new CControlClass();
ControlObj->functionOne();
}

In win environment, program runs really good.

On Linux (g++ 4.1) it compiles, it will write the log related to
readConfFile but when functionOne calls the Logger (called from main),
a private variable of CLoggerClass (needed to tailor detalization of
output) is not anymore referenced. That causes a segmentation fault.

I was able to recover from SEGFAULT, putting LoggerObj=new
CLoggerClass("some_log_file.log") into the constructor of
ControlClass... but it will not write anything when called by
functionOne,Two,Three... and when called by readConfFile, it will
write the log into the configuration file

Can you please explain what's the matter?
I 'd like to understand why such a big difference exists in Linux and
Win variable scope in Standard C++.

Thanks,
Mark

SG 02-28-2011 03:14 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
On 28 Feb., 13:39, Mark wrote:
> [...]
> The implementation is very similar both in Win and *NIX.
> CControlClass incorporates CLoggerClass this way.
> *LoggerObj is declared as private member of CControlClass.
> (CLoggerClass *LoggerObj)
>
> CControlClass::CControlClass()
> { readConfFile("somefile.conf"); }
>
> int CControlClass::readConfFile(const char * somefile){
> //do some parsing
> LoggerObj=new CLoggerClass("some_log_file.log");
> LoggerObj->writeLog(some_const_int,some_char_array_or_string stream)
> }
>
> int CControlClass::functionOne()
> {
> //something
> LoggerObj->writeLog(...,...)}
>
> //main.cpp
> int main(int argc, char** argv)
> {
> *CControlClass *ControlObj=new CControlClass();
> ControlObj->functionOne();
> }


btw, this looks like a Java/C# programmer is trying to import his
programming style into C++. You know that there is no garbage
collection in C++ and that you should delete the things you created
with new, right? If not, stop immediately and get hold of a decent C++
book. Forcing a Java/C# programming style in C++ won't do you any
good. The languages are just too different.

> In win environment, program runs really good.
>
> On Linux (g++ 4.1) it compiles, it will write the log related to
> readConfFile but when functionOne calls the Logger (called from main),
> a private variable of CLoggerClass (needed to tailor detalization of
> output) is not anymore referenced. That causes a segmentation fault.
>
> I was able to recover from SEGFAULT, putting LoggerObj=new
> CLoggerClass("some_log_file.log") into the constructor of
> ControlClass... but it will not write anything when called by
> functionOne,Two,Three... and when called by readConfFile, it will
> write the log into the configuration file
>
> Can you please explain what's the matter?


Sorry, I can't. Not with so little information. But you may want to
simplify your code so you can show a short and complete example of the
exact code that you tested and didn't work like intended. Chances are,
you did something wrong and looking for the bug in the wrong place.

Cheers!
SG

jacob navia 02-28-2011 03:42 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
Le 28/02/11 16:14, SG a écrit :
> On 28 Feb., 13:39, Mark wrote:
>> [...]
>> The implementation is very similar both in Win and *NIX.
>> CControlClass incorporates CLoggerClass this way.
>> *LoggerObj is declared as private member of CControlClass.
>> (CLoggerClass *LoggerObj)
>>
>> CControlClass::CControlClass()
>> { readConfFile("somefile.conf"); }
>>
>> int CControlClass::readConfFile(const char * somefile){
>> //do some parsing
>> LoggerObj=new CLoggerClass("some_log_file.log");
>> LoggerObj->writeLog(some_const_int,some_char_array_or_string stream)
>> }
>>
>> int CControlClass::functionOne()
>> {
>> //something
>> LoggerObj->writeLog(...,...)}
>>
>> //main.cpp
>> int main(int argc, char** argv)
>> {
>> CControlClass *ControlObj=new CControlClass();
>> ControlObj->functionOne();
>> }

>
> btw, this looks like a Java/C# programmer is trying to import his
> programming style into C++. You know that there is no garbage
> collection in C++ and that you should delete the things you created
> with new, right? If not, stop immediately and get hold of a decent C++
> book. Forcing a Java/C# programming style in C++ won't do you any
> good. The languages are just too different.


There is no point in deleting anything since it is the main() function
and the OS will cleanup stuff anyway.


Jonathan Lee 02-28-2011 03:50 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
On Feb 28, 6:39*am, Mark <nic...@gmail.com> wrote:
> Can you please explain what's the matter?
> I 'd like to understand why such a big difference exists in Linux and
> Win variable scope in Standard C++.
>
> Thanks,
> Mark



My best guess is that CControlClass has a destructor that deletes
LoggerObj. At some point, an instance of CControlClass gets copied
which results in a copy of the LoggerObj pointer, but the destructor
destroys the thing being pointed to. When you use the copy, LoggerObj
doesn't exist anymore.

Sometimes these objects will still sorta work, sometimes not. Depends
how much of the destroyed object is "still around". They certainly
aren't expected to work, but you can get this inconsistent behavior.

--Jonathan


jacob navia 02-28-2011 05:17 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
Le 28/02/11 16:46, Leigh Johnston a écrit :
>> There is no point in deleting anything since it is the main() function
>> and the OS will cleanup stuff anyway.

>
> Here are three adjectives that describe you as a programmer:
>
> 1) cowboy
> 2) sloppy
> 3) slapdash
>
> I will let you choose which one you want.
>
> /Leigh


There are several memory management and memory use strategies. I have
enumerated the most used ones in my tutorial (about the C language,
not the C++ language) available here:

http://www.cs.virginia.edu/~lcc-win32/

Some of the principles there apply here, specifically the 'Never free()'
strategy.

This strategy avoids all problems associated with free() (in C++
"delete") by never freeing or deleting any memory and allowing the
OS to clean up everything much more efficiently.

This strategy is indicated for transient programs, that allocate a
lot of memory, and almost never release anything until they exit.

A compiler system is such a transient program. It will start, gobble
megabytes of memory for tables, (symbol tables, source file tables
whatever) and will exit with most of the memory retained until the
end. It is a waste of time to free() in this context, or to delete.
The OS will cleanup probably in a OS specific manner in a very EFFICIENT
way, so it is better to avoid any problems with delete
and just keep all memory until the program exits.

Another similar programs are utilities like "grep" for instance.
They start, use some memory, then exit.

Obviously you seem to think that the "never use delete" strategy
is used only by "cowboys" or sloppy programmers. Please explain why.

jacob

SG 02-28-2011 05:35 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
On 28 Feb., 16:42, jacob navia wrote:
> Le 28/02/11 16:14, SG a crit :
> > On 28 Feb., 13:39, Mark wrote:
> >> [...]
> >> The implementation is very similar both in Win and *NIX.
> >> CControlClass incorporates CLoggerClass this way.
> >> *LoggerObj is declared as private member of CControlClass.
> >> (CLoggerClass *LoggerObj)

>
> >> * *int CControlClass::readConfFile(const char * somefile){
> >> * * *//do some parsing
> >> * * *LoggerObj=new CLoggerClass("some_log_file.log");
> >> * * *LoggerObj->writeLog(some_const_int,some_char_array_or_string stream)
> >> * *}

>
> > btw, this looks like a Java/C# programmer is trying to import his
> > programming style into C++. You know that there is no garbage
> > collection in C++ and that you should delete the things you created
> > with new, right? [...]

>
> There is no point in deleting anything since it is the main() function
> and the OS will cleanup stuff anyway.


*sigh*
No, it's not restricted to the main function (see above). And it comes
with mo surprize that anything one writes here is subject to
nitpicking. I probably should have added a "generally" in there
somewhere... If it makes you feel any better, I have no problem with
you allocating memory once in a main function and not explicitly
releasing it or any other popular singleton implementation strategy
which does not destruct the object.

Cheers!
SG

itaj sherman 02-28-2011 06:19 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
On Feb 28, 7:17 pm, jacob navia <ja...@spamsink.net> wrote:
> Le 28/02/11 16:46, Leigh Johnston a crit :
>
> >> There is no point in deleting anything since it is the main() function
> >> and the OS will cleanup stuff anyway.

>


>
> Some of the principles there apply here, specifically the 'Never free()'
> strategy.
>
> This strategy avoids all problems associated with free() (in C++
> "delete") by never freeing or deleting any memory and allowing the
> OS to clean up everything much more efficiently.
>


If you really mean it, it would need a more careful explanation than
that.
delete is destructor + deallocation.

I would immediately agree that memory deallocation operations of
objects can be skipped when you have a more global memory management.
It could be the process ending, or it could be some memory pool
library allocator or garbage collector library.
However, claiming that you can skip destructors would need a more
careful explanation. Even when I have some memory managment that
collectes my memory garbage, I would keep away from skipping
destructors, especially as a general notion.

itaj



jacob navia 02-28-2011 06:44 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
Le 28/02/11 19:19, itaj sherman a écrit :
> On Feb 28, 7:17 pm, jacob navia<ja...@spamsink.net> wrote:
>> Le 28/02/11 16:46, Leigh Johnston a crit :
>>
>>>> There is no point in deleting anything since it is the main() function
>>>> and the OS will cleanup stuff anyway.

>>

>
>>
>> Some of the principles there apply here, specifically the 'Never free()'
>> strategy.
>>
>> This strategy avoids all problems associated with free() (in C++
>> "delete") by never freeing or deleting any memory and allowing the
>> OS to clean up everything much more efficiently.
>>

>
> If you really mean it, it would need a more careful explanation than
> that.
> delete is destructor + deallocation.
>
> I would immediately agree that memory deallocation operations of
> objects can be skipped when you have a more global memory management.
> It could be the process ending, or it could be some memory pool
> library allocator or garbage collector library.
> However, claiming that you can skip destructors would need a more
> careful explanation. Even when I have some memory managment that
> collectes my memory garbage, I would keep away from skipping
> destructors, especially as a general notion.
>
> itaj
>
>


It depends on what the destructor does. If the destructor starts just
managing memory (for instance deletes embedded objects) it is not
necessary to use it if the program is exiting anyway.

Other stuff (like open files, for instance) are closed anyway
automatically by the runtime, so it is not necessary to take care of
that also.


jacob navia 02-28-2011 06:56 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
Le 28/02/11 18:31, Leigh Johnston a écrit :

> One should get into the habit of always deleting what you new to avoid
> memory leaks. Programs which allocate everything up front and require no
> deallocations until program termination are few and far between;


I mentioned two examples: a compiler and other command line utilities.

In general all transient programs (i.e. those designed to do one task
and exit immediately) can benefit from this strategy.

> your
> eschewing of deletes mostly smells of premature optimization which would
> result in code that is a nightmare to maintain as you would have to
> constantly worry if a particular allocation is a one-off or if leaked
> would result in unacceptable increased memory usage during program run.
>


If your allocation concerns an important chunk of memory yes, you
should delete it if you recycle objects. In many cases however
(and in the case at hand in the example that started this discussion)
there is no need to worry about it.

> Perhaps you would prefer a garbage collected language such as Java?
>


My compiler system (lcc-win) offers in its standard distribution a
garbage collector. It is used also in C++ programs. But obviously
you think (as all those "language patriots" that C++is the best
language on the world, and that Java is a kind of atrocious horror
that will scare me (and others) if you just mention it.

> Perhaps you would prefer a garbage collected language such as Java?
>


Perhaps I would prefer that C++ people would acknowledge this
huge HOLE in their (so complicated) language and plug it some time...

But what, learning from other languages and using the good features they
have?

NEVER. C++ is the best and there is nothing outside, only BAD languages.

> Here are three adjectives which *still* describe you as a *C++* programmer:
>
> 1) cowboy
> 2) sloppy
> 3) slapdash
>


Yes, that is your opinion. Who cares about it? Surely not me.

I know this kind of people that pontificate in newsgroups, distributing
"good" or "bad" points without proposing any arguments really.

Why would the absence of "delete" when the program is exiting be "bad"?

And this strategy is very easy to maintain: Just plug in a garbage
collector and you are done.

jacob


itaj sherman 02-28-2011 06:57 PM

Re: Object/variable scope problems (Linux and Win comparison)
 
On Feb 28, 8:44 pm, jacob navia <ja...@spamsink.net> wrote:
> Le 28/02/11 19:19, itaj sherman a crit :
>
>
>
> > On Feb 28, 7:17 pm, jacob navia<ja...@spamsink.net> wrote:
> >> Le 28/02/11 16:46, Leigh Johnston a crit :

>
> >>>> There is no point in deleting anything since it is the main() function
> >>>> and the OS will cleanup stuff anyway.

>
> >> Some of the principles there apply here, specifically the 'Never free()'
> >> strategy.

>
> >> This strategy avoids all problems associated with free() (in C++
> >> "delete") by never freeing or deleting any memory and allowing the
> >> OS to clean up everything much more efficiently.

>
> > If you really mean it, it would need a more careful explanation than
> > that.
> > delete is destructor + deallocation.

>
> > I would immediately agree that memory deallocation operations of
> > objects can be skipped when you have a more global memory management.
> > It could be the process ending, or it could be some memory pool
> > library allocator or garbage collector library.
> > However, claiming that you can skip destructors would need a more
> > careful explanation. Even when I have some memory managment that
> > collectes my memory garbage, I would keep away from skipping
> > destructors, especially as a general notion.

>
> It depends on what the destructor does. If the destructor starts just
> managing memory (for instance deletes embedded objects) it is not
> necessary to use it if the program is exiting anyway.
>


Yes, in a single frase what I meant is: it depends on what the
destructor does.

Strictly speaking, "just managing memory" is not the same as "deletes
embedded objects", for the same reason. The destructors of some
embedded objects might release other resources (other than allocated
memory), and you have to specify in some way what happens to them,
just the same way you sepcify what happens to the memory allocations.
I'd think someone has to be able to give a very good reason for
choosing to go that path, it shouldn't be commented as a general
notion (skipping destruction that is). That's what I meant by "more
careful explanation".

itaj


All times are GMT. The time now is 09:12 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.