Object/variable scope problems (Linux and Win comparison)

M

Mark

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_stringstream)
}

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
 
S

SG

[...]
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_stringstream)
}

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
 
J

jacob navia

Le 28/02/11 16:14, SG a écrit :
[...]
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_stringstream)
}

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.
 
J

Jonathan Lee

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
 
J

jacob navia

Le 28/02/11 16:46, Leigh Johnston a écrit :
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
 
S

SG

Le 28/02/11 16:14, SG a crit :
[...]
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_stringstream)
   }
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
 
I

itaj sherman

Le 28/02/11 16:46, Leigh Johnston a crit :



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
 
J

jacob navia

Le 28/02/11 19:19, itaj sherman a écrit :
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.
 
J

jacob navia

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
 
I

itaj sherman

Le 28/02/11 19:19, itaj sherman a crit :






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
 
J

jacob navia

Le 28/02/11 18:35, SG a écrit :
*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.

It is not nitpicking. It is an interesting strategy: always allocate
and never free, that results in interesting discussions (see the answer
of Mr Johnston).

jacob

P.S. I think that outside a conscious memory allocation strategy you
are obviously RIGHT.
 
J

jacob navia

Le 28/02/11 19:59, itaj sherman a écrit :
Even if you had something sensible to say, it's lost in your
overwhelming waves of bad manners.

itaj

Good point. Let's try to discuss in a civilized manner, without
just falling into a childish attitude of calling people names...
 
P

Paul

jacob navia said:
Le 28/02/11 18:31, Leigh Johnston a écrit :


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.


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.


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 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.


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
Well put mate, you certainly put him in his proper place *thumbs up*
 
J

jacob navia

Le 28/02/11 19:47, Leigh Johnston a écrit :
Another adjective for you:

4) shoddy

/Leigh

Incredible deep argument Mr Johnston. It has really a lot of well
thought principles in it.

:)

But maybe can you explain to a "shoddy" "cowboy" "sloppy" programmer
why a program should waste time and resources cleaning up objects
that are of no importance since it is going to exit anyway?

I make the distinction between objects that NEED recycling (big objects
for instance, that if maintained beyond their useful lifetime would
provoke an out of memory condition), and small objects that could
never provoke anything bad.

This distinctions are not just empty words. A C++ program can spend
a LOT of time cleaning up objects without any useful reason since
it is done at program exit...

That is my point.
 
J

jacob navia

Le 28/02/11 20:22, Leigh Johnston a écrit :
The point is that you are a shoddy C++ programmer if you genuinely
believe this crap you are posting. Stick to Java and its GC mate; C++ is
not for you.


Well Mister, apparently you can't discuss in a civilized manner without
calling people names.

And yes, if a customer pays me to program in Java I will program in
Java without thinking that I am doing something awful, the same as in
C++. Last september I had a contract to program in Visual Basic and
Access data base. And I did it in Visual Basic and Access.

Today I am programming in objective c and an iPhone. It is a very
small language but is great. And there this strategy doesn't work
very well, you have to release each piece of memory/resources you use.

Applications never exit really in most cases, so a strategy like I am
proposing here would be catastrophic. So I do not use it.

Am I a "shoddy" programmer? (and all other "adjectives" you use)?

For you, yes.

But what *I* think is important is the opinion *my customers*
have of me. Your opinion doesn't really count.

So you can go on calling me with any adjectives you may want to use.

:)

Yours sincerely

jacob
 
M

Mark

Le 28/02/11 20:22, Leigh Johnston a crit :




Well Mister, apparently you can't discuss in a civilized manner without
calling people names.

And yes, if a customer pays me to program in Java I will program in
Java without thinking that I am doing something awful, the same as in
C++. Last september I had a contract to program in Visual Basic and
Access data base. And I did it in Visual Basic and Access.

Today I am programming in objective c and an iPhone. It is a very
small language but is great. And there this strategy doesn't work
very well, you have to release each piece of memory/resources you use.

Applications never exit really in most cases, so a strategy like I am
proposing here would be catastrophic. So I do not use it.

Am I a "shoddy" programmer? (and all other "adjectives" you use)?

For you, yes.

But what *I* think is important is the opinion *my customers*
have of me. Your opinion doesn't really count.

So you can go on calling me with any adjectives you may want to use.

:)

Yours sincerely

jacob

Sorry I didn't want to raise this confusion.
FYI I have never programmed in Java, for my job I often use pure C,
Perl and shell scripts, sometime python. Object programming is a thing
I use very seldom and therefore I have problems even in the
application's project phase.
Anyway I found the stupid bug: simply I called the constructor of
LoggerClass with an uninitialized variable. This was causing the
misbehaviour.
Sorry if I don't seem serious Leigh, but I do agree with Jacob Navia
(on the last part of his 1st reply)
There is no point in deleting anything since it is the main() function
and the OS will cleanup stuff anyway.

I have no problems related to memory limit. As the unix part will
contain just 1 father and 1 or 2 children, a wait/waitpid are enough
to ensure a proper cleanup of the heap when main exits.
If you don't agree, please argue and demonstrate I am not right, but
please in a civil manner.

Mark.
 
J

Joshua Maurice

Le 28/02/11 18:31, Leigh Johnston a crit :

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.

Reasonable people will not argue that garbage collected systems are
purely inferior to manual memory management systems. Having said that,
it is rather difficult to mix implicit destructor calls and garbage
collection. It is not a simple problem with simple answers.

C++ has largely the same design goals as C, which is to be a portable
assembly language, and to be cost competitive with assembly. Garbage
collection simply does not fit this design paradigm of C++, especially
when it's largely incompatible with implicit destructor calls - the
heart of C++.
 
J

Juha Nieminen

SG said:
[...]
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_stringstream)
}

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?

In fact, why is he using 'new' at all? There's no need, and 'new' is
only making the program less efficient than instantiating the objects
on the stack.

There's a reason C++ uses RAII. That fact should always be used to
one's advantage.
 
S

SG

SG said:
[...]
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?

  In fact, why is he using 'new' at all? There's no need, and 'new' is
only making the program less efficient than instantiating the objects
on the stack.

Good point! I somehow forgot to mention this.

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,822
Latest member
israfaceZa

Latest Threads

Top