- something happened to malloc? - 12 Updates
- mysterious destructors - 3 Updates
- size of a variable - 1 Update
- SObjectizer: a tool for working with actors in C++ and some slides about it - 1 Update
- mysterious destructors - 8 Updates
Torsten Mueller <muellerto@runbox.com>: Feb 18 09:29AM +0100 My C++ application compiled for many years with gcc, up to current version 4.9.2. But now after a compiler update it suddenly says "malloc is undefined", and this message comes from far above, from inside the cstdlib header. Note: I don't use malloc at all, not a single time. My code is proper C++. But C++ himself uses malloc in the new operator. What I had to do for getting a workaround was to include stdlib.h before cstdlib - but can this be the solution??? cstdlib still includes stdlib.h, of course, it always did. In my application I use also boost (1.57). And boost has an own cstdlib header. Could this be the reason? Has anyone had this problem in the last time, malloc is undefined? T.M. |
"Lőrinczy Zsigmond" <zsiga@nospam.for.me>: Feb 18 09:47AM +0100 Please quote the complete message, it's not clear if this is a compiler-message or a linker-message. |
"Øyvind Røtvold" <orotvold@gmail.com>: Feb 18 09:56AM +0100 > What I had to do for getting a workaround was to include stdlib.h before > cstdlib - but can this be the solution??? cstdlib still includes > stdlib.h, of course, it always did. Is cstdlib supposed to be self-contained? If so try to include it first in your source file. If it fails there's an error in your compiler which should be reported - or, more likely, an error in your compiler installation that you should fix. > In my application I use also boost (1.57). And boost has an own cstdlib > header. Could this be the reason? If you include this cstdlib header then anything boost think proper could happen, including what you describes. Remove boots from the equation and try again. -- .. Ųyvind - soon to appear in a kill file near you. .. Ignorance can be cured; stupidity is forever. |
Torsten Mueller <muellerto@runbox.com>: Feb 18 10:07AM +0100 > Please quote the complete message, > it's not clear if this is a compiler-message or a linker-message. Sure it is clear. I never spoke about the linker, I spoke about the compiler and headers. It's a true compiler problem, happening again and again in every single source file. T.M. |
"Lőrinczy Zsigmond" <zsiga@nospam.for.me>: Feb 18 10:15AM +0100 > > Please quote the complete message, > It's a true compiler problem, > happening again and again in every single source file. That's why you don't quote the complete message. Ok. |
Torsten Mueller <muellerto@runbox.com>: Feb 18 10:19AM +0100 > Is cstdlib supposed to be self-contained? I'm sure. > If it fails there's an error in your compiler which should be reported > - or, more likely, an error in your compiler installation that you > should fix. I try to get a preprocessor output this afternoon to see the real code and which header is really included and which conditional code is indeed compiled. Interesting is that cstdlib also uses a handful of other primitive C-functions, about 20, but only malloc is unknown. T.M. |
Torsten Mueller <muellerto@runbox.com>: Feb 18 10:21AM +0100 >> It's a true compiler problem, >> happening again and again in every single source file. > That's why you don't quote the complete message. Ok. Dear Hungarian friend, I can't quote because I'm currently not on this machine, OK? T.M. |
"Lőrinczy Zsigmond" <zsiga@nospam.for.me>: Feb 18 11:04AM +0100 On 2015-02-18 09:29, Torsten Mueller wrote: > In my application I use also boost (1.57). And boost has an own cstdlib > header. Could this be the reason? But of course. Try to complie boost-less example programs. |
David Brown <david.brown@hesbynett.no>: Feb 18 11:38AM +0100 On 18/02/15 09:29, Torsten Mueller wrote: > header. Could this be the reason? > Has anyone had this problem in the last time, malloc is undefined? > T.M. The usual way to proceed with this sort of thing is to figure out a minimum sample that demonstrates the problem - this should help you figure out if boost is the problem or there is something else wrong. And then you can post the example along with the error messages (when you are on the right computer, of course). Also include details of the compiler and command-line switches. You said that your code worked with gcc up to 4.9.2 - but after an update it failed. Since 4.9.2 is the latest released version of gcc, are you trying a development version? Did you get the new version from a different place (in which case it might be packaged with different libraries or other differences)? |
Torsten Mueller <muellerto@runbox.com>: Feb 18 12:10PM +0100 > You said that your code worked with gcc up to 4.9.2 - but after an > update it failed. Since 4.9.2 is the latest released version of gcc, > are you trying a development version? No, it's official 4.9.2. But on a Linux machine you always have still other parts of software defining the concrete build environment, especially glibc and libc++ (and a lot of others ...) My situation is as follows: I have two Linux machines, an old one and a new one, both with gcc 4.9.2, but with a different bunch of libs. The old one compiles fine, the new one doesn't know malloc in cstdlib. Sure I have glibc on this machine, sure I have also all the glibc-headers, sure malloc is an existing, documented and well known function. I never changed anything in these files or in the permissions, all is standard, but cstdlib doesn't know malloc. OK, for me it's a hint that noone says, yes, that's right, they changed something last sunday in glibc, malloc is banned for ever, or so. T.M. |
David Brown <david.brown@hesbynett.no>: Feb 18 01:10PM +0100 On 18/02/15 12:10, Torsten Mueller wrote: > No, it's official 4.9.2. But on a Linux machine you always have still > other parts of software defining the concrete build environment, > especially glibc and libc++ (and a lot of others ...) OK, that's clearer - you said "after a compiler update", rather than "after a system update" or "after a library update". > OK, for me it's a hint that noone says, yes, that's right, they changed > something last sunday in glibc, malloc is banned for ever, or so. > T.M. Can you do a quick comparison of the headers between the machines, to see if something has dramatically changed there? It won't be the libraries that have changed, as you haven't got that far (they only affect the linking stage). |
scott@slp53.sl.home (Scott Lurndal): Feb 18 02:17PM >OK, for me it's a hint that noone says, yes, that's right, they changed >something last sunday in glibc, malloc is banned for ever, or so. >T.M. Compile on both systems using -E and compare the resulting output. That should tell you where, exactly, the malloc is defined (and the path to get there) in the working example; which should lead you to the difference. IIRC, some versions of gcc used to implicitly declare malloc. |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 18 12:22AM I have written the following program: #include <iostream> #include <ostream> struct c { int v; c( int const x ): v( x ) { ::std::cout << "constructor of instance #" << v << ".\n"; } ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } void print(){ ::std::cout << "I am instance #" << v << ".\n"; }}; int main() { c o = * new c( 1 ); o.print(); o = * new c( 2 ); /* overwrite */ o.print(); } The program prints: constructor of instance #1. I am instance #1. constructor of instance #2. I am instance #2. destructor of instance #2. In the line marked with »/* overwrite */«, instance #1 in the variable »o« is overwritten with another instance of the same class c if I understand it correctly. I thought that this overwriting kind-of »destroys« the instance #1 and that this might invoke the destructor of instance #1. But no, it does never print »destructor of instance #1.«. I am still a beginner with respect to some parts of C++, so I have to ask here why my expectations are wrong. |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 18 12:59AM >> o = * new c( 2 ); /* overwrite */ >> o.print(); } >By assigning another instance to the pointer you lost the first. Raw But both »o« and »* new c( 2 )« are not pointers, but rather an object and a temporary, respectively, as far as I understand it. »new c( 2 )« is a pointer, but »*« makes a temporary from the pointer, as far as I understand it. So, the assignment »o = * new c( 2 )« has an object on the left and a temporary on the right. >Nay my friend. You have demonstrated a memory leak. (I am aware that the »new« creates a memory leak missing the corresponding »delete«, but this was not my primary concern, so - for simplification - I omitted the »delete«.) |
ram@zedat.fu-berlin.de (Stefan Ram): Feb 18 02:03PM >other hand, you have two values (1 and 2), copy them over across >instances and print out with misleading messages, so there is no wonder So, in C++, an assignment of the kind object0 = object1 can be thought of as a field-by-field copy (at least in the simple case of POD-like objects) from object1 to object0 that does not change the existence status of object0 or object1. |
David Brown <david.brown@hesbynett.no>: Feb 18 10:42AM +0100 On 17/02/15 23:51, Barry Schwarz wrote: >>> uint8_t? >> The rules of C - a "char" is the smallest addressable unit of memory. > That doesn't stop sub-byte bit fields. Bit-fields cannot be accessed except as part of their containing struct. In particular, you cannot take the address of a bitfield (§6.5.3.2 of N1570, if you want chapter and verse). > There is also no restriction > in the standard that prohibits multiple objects sharing an address. I can't find the right paragraph for this one (but I'm sure others here or in comp.lang.c can do so - the rules being the same for C and C++). But different objects must have different addresses, unless they are part of a union. This is why classes without data members (or virtual functions) have size 1 rather than size 0 - the different addresses allow them to be distinguished. |
eao197@gmail.com: Feb 18 01:32AM -0800 SObjectizer[1] is a small framework which was created under influence of several approaches like Actor Model and Publish/Subscribe. It was used as in-house tool for developing several business-critical applications. It is distributed as OpenSource project under NewBSD-license since 2006. But unlike CAF (former libcppa) or Theron frameworks it is not widely known because almost all articles and docs were in Russian. Now I glad to represent two introductory presentations about this tool in English. I hope someone will find them interesting and useful. The presentations could be found here: http://eao197.blogspot.com/2015/02/prog-two-introductory-presentations.html Best regards, Yauheni --- [1] https://sourceforge.net/projects/sobjectizer/ |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 18 12:30AM On 18/02/2015 00:22, Stefan Ram wrote: > it does never print »destructor of instance #1.«. > I am still a beginner with respect to some parts of C++, so > I have to ask here why my expectations are wrong. That code is mental mate; you have two memory leaks as you are create two objects on the heap and in the first case you are *copy constructing* 'o' on the stack with one of them and in the second case you are *assigning* to o with one of them. This is what you code should look like: c o(1); // construction o = c(2); // assignment No heap allocation with new required. /Flibble |
Christopher Pisz <nospam@notanaddress.com>: Feb 17 06:50PM -0600 On 2/17/2015 6:22 PM, Stefan Ram wrote: > it does never print »destructor of instance #1.«. > I am still a beginner with respect to some parts of C++, so > I have to ask here why my expectations are wrong. Nay my friend. You have demonstrated a memory leak. By assigning another instance to the pointer you lost the first. Raw pointers do not automatically invoke the destructor when assigned. After all, you may not want it destroyed, but simply to point to something else, if you had another way of getting at it, like a second pointer elsewhere. As is, it is dangling, lost forever. If you would like to have that behavior, you may want to use a std::shared_ptr or one of its kin. ----- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble" So, I won't be able to see or respond to any such messages ----- |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 18 12:55AM On 18/02/2015 00:50, Christopher Pisz wrote: > words: "Rick C. Hodgins", "Flibble" > So, I won't be able to see or respond to any such messages > ----- Mr Flibble is very cross. |
"Christopher J. Pisz" <cpisz@austin.rr.com>: Feb 17 07:20PM -0600 On 2/17/2015 6:59 PM, Stefan Ram wrote: > the pointer, as far as I understand it. > So, the assignment »o = * new c( 2 )« has an object on the > left and a temporary on the right. True, kind of. the <new> returns a pointer. You de-referenced it, and assigned it to an object on the stack, whom was already default constructed, but you saw no message for that or the assignment because you didn't implement the default constructor or the assignment operator yourself. So really, you have 3 instances and the message is erroneous, because it is actually the instance on the stack getting destroyed, while both on the heap are leaked. > (I am aware that the »new« creates a memory leak missing the > corresponding »delete«, but this was not my primary concern, > so - for simplification - I omitted the »delete«.) Oh, ok, I didn't realize you did it on purpose. Implement the default constructor and the assignment operator with messages and see if it makes sense. |
"Lőrinczy Zsigmond" <nospam@for.me>: Feb 18 06:50AM +0100 On 2015.02.18. 1:22, Stefan Ram wrote: > { ::std::cout << "constructor of instance #" << v << ".\n"; } > ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } > void print(){ ::std::cout << "I am instance #" << v << ".\n"; }}; If your idea is making constructors and debuggers visible, then you are on the right way, but it still could be improved struct c { int v; c( int const x ): v( x ) { ::std::cout << "constructor of instance #" << v << ".\n"; } c(const c &from): v(from.v) { ::std::cout << "copy constructor of instance #" << v << ".\n"; } c& MyClass::operator= (const c &from) { printf ("assignment (operator=) new=%d old=%d\n", this->v, other->v); this->v = other= v; /* do we need this? */ return *this; } ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } void print(){ ::std::cout << "I am instance #" << v << ".\n"; }}; Note: either include <cstdio> or change 'printf' to a bunch of <<'s |
"Lőrinczy Zsigmond" <nospam@for.me>: Feb 18 06:57AM +0100 > ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } > void print(){ ::std::cout << "I am instance #" << v << ".\n"; }}; > Note: either include <cstdio> or change 'printf' to a bunch of <<'s Lot of bugs here:) c& MyClass::operator= (const c &from) { printf ("assignment (operator=) new=%d old=%d\n", from.v, this->v); this->v = from.v; /* do we need this? */ return *this; } |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 18 12:44AM -0600 ram@zedat.fu-berlin.de (Stefan Ram) wrote in news:destructors- > In the line marked with »/* overwrite */«, instance #1 in the > variable »o« is overwritten with another instance of the same > class c if I understand it correctly. This is because you have mixed up instances with values. In your program you have 3 instances of class c, 2 of them are leaked and so there is only a single destructor call when the object o goes out of scope. On the other hand, you have two values (1 and 2), copy them over across instances and print out with misleading messages, so there is no wonder one gets confused. You can have an example with 2 instances (of class c) and no memory leaks as well: #include <iostream> #include <ostream> #include <memory> struct c { int v; c( int const x ): v( x ) { ::std::cout << "constructor of instance #" << v << ".\n"; } ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } void print(){ ::std::cout << "I am instance #" << v << ".\n"; }}; int main() { std::unique_ptr<c> o(new c( 1 )); o->print(); o = std::unique_ptr<c>(new c( 2 )); /* overwrite */ o->print(); } This prints: constructor of instance #1. I am instance #1. constructor of instance #2. destructor of instance #1. I am instance #2. destructor of instance #2. For some more fun, here is another example having 2 instances and no memory leaks. This one is probably even more confusing ;-) #include <iostream> #include <ostream> struct c { mutable int v; c( int const x ): v( x ) { ::std::cout << "constructor of instance #" << v << ".\n"; } void operator=(const c& y) const {v = y.v;} ~c(){ ::std::cout << "destructor of instance #" << v << ".\n"; } void print() const { ::std::cout << "I am instance #" << v << ".\n"; }}; int main() { const c& o = c( 1 ); o.print(); o = c( 2 ); /* overwrite */ o.print(); } constructor of instance #1. I am instance #1. constructor of instance #2. destructor of instance #2. I am instance #2. destructor of instance #2. |
"Tobias Müller" <troplin@bluewin.ch>: Feb 18 06:50AM > it does never print »destructor of instance #1.«. > I am still a beginner with respect to some parts of C++, so > I have to ask here why my expectations are wrong. There seems to be a misunderstanding of the difference between objects and pointer to objects. I suspect that you are coming from java where this distinction is not visible. A reference in Java (often just called an object) corresponds to a _pointer_ in C++. This is what your program actually means, step by step: int main() { c o; // creates an object (not a reference!) on the stack { // temporary scope for second statement in your code c* anon = new c( 1 ); // create an anonymous object on the heap o = *anon; // assign the _content_ of the anonymous object to o. } // pointer to anonymous object is lost -> memory leak o.print(); { // temporary scope for 4th statement in your code c* anon = new c( 2 ); // create an anonymous object on the heap o = *anon; // assign the _content_ of the anonymous object to o. } // pointer to anonymous object is lost -> memory leak o.print(); } Tobi |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment