|
You'll want to use the binary stream IO functions (fread and fwrite) to do binary IO, not the text functions like fprintf.
|
# ? May 4, 2011 19:27 |
|
|
# ? Apr 28, 2024 20:28 |
|
Also, if you're going to be writing structures to files you definitely don't want to use the endian-safe per-byte thing, because that won't write the bytes out in the order in which they occur!
|
# ? May 4, 2011 20:02 |
|
Does one of you know how pairs work? I'm totally clueless. I'm working on a program that needs to be fast and memory efficient, and I recently decided that the value in a map I have should be 2 ints instead of one. Using pairs jumps out at me, because the key/value is also a pair. So each map entry would be, pair<char*, pair<int,int>>. In short, I'd really like to avoid using an int* here, because allocating them dynamically on the heap would be really inefficient, and I don't want to deal with block allocation. What would be ideal is just an 8-byte stack object, like a uint_64 (that I could just byte shift, etc), but I want this code to compile on 32bit machines, so that rules that out. I guess my fundamental question is - what exactly is the memory involved in a pair? Are pairs pointers that need to be stored, or some compiler trickery (that somehow lumps them together)? What would using pairs cost me, in terms of bytes, per map entry? I've had a really hard time finding reference material for this, so sorry for the simple questions. e: spelling edit Clobbersaurus fucked around with this message at 21:26 on May 4, 2011 |
# ? May 4, 2011 21:21 |
|
Clobbersaurus posted:I guess my fundamental question is - what exactly is the memory involved in a pair? Are pairs pointers that need to be stored, or some compiler trickery (that somehow lumps them together)? What would using pairs cost me, in terms of bytes, per map entry? I've had a really hard time finding reference material for this, so sorry for the simple questions. Basically, "compiler trickery". A pair is essentually struct { T1 first; T2 second; }.
|
# ? May 4, 2011 21:28 |
|
Clobbersaurus posted:I'm working on a program that needs to be fast and memory efficient, and I recently decided that the value in a map I have should be 2 ints instead of one. Using pairs jumps out at me, because the key/value is also a pair. So each map entry would be, code:
quote:I guess my fundamental question is - what exactly is the memory involved in a pair? Write your program to best model your problem. Use the things that C++ gives you, and don't feel like you need to do better than the obvious solution until you can prove the obvious solution is inadequate. It almost never is. Brecht fucked around with this message at 23:08 on May 4, 2011 |
# ? May 4, 2011 23:05 |
Doesn't a map<typeA,typeB> make a pair<typeA,typeB>? So clobber_map entries are pair<string,my_struct>?
|
|
# ? May 5, 2011 00:25 |
|
floWenoL posted:Basically, "compiler trickery". A pair is essentually struct { T1 first; T2 second; }. Thanks - I'll move ahead with the pair and check the memory when I'm finished - by the sound of it, it'll just take 4 extra bytes per entry, and the pair just keeps them together in memory. Brecht posted:Why not When I said I needed it to be memory efficient, I meant I'll have on the order of a hundred million entries in this map. If I can avoid having an extra pointer it'll save 400 megabytes of memory, so I do care about the gritty details. I agree with you in principle though. By the gist of floWenoL's post, the struct and pair should be equivalent (and hopefully I can deal with pairs on the stack - not sure if this is possible with structs). A MIRACLE posted:Doesn't a map<typeA,typeB> make a pair<typeA,typeB>? So clobber_map entries are pair<string,my_struct>? Basically you create the pair, and then give it to the map (if that's your question). In his example you're right, except "my_struct" should be "my_two_ints". It's neat because when you access the entries you get the pair back, so you can get the key or value.
|
# ? May 5, 2011 15:50 |
|
Clobbersaurus posted:When I said I needed it to be memory efficient, I meant I'll have on the order of a hundred million entries in this map. If I can avoid having an extra pointer it'll save 400 megabytes of memory, so I do care about the gritty details. I agree with you in principle though. By the gist of floWenoL's post, the struct and pair should be equivalent (and hopefully I can deal with pairs on the stack - not sure if this is possible with structs). Yes, you can put an instance of any type on the stack in C++ (of course, that type itself might internally allocate memory on the free store if it wants, i.e. an std::map or std::string). Sorry to be that guy, but even though you haven't given us much information you are pretty much definitely going about whatever it is that you want to do in the wrong way. Your scenario already implies occupying over 2 gigs of memory for storing this data alone. I highly doubt you actually need hundreds of millions of elements all in memory at once. If you're in 32-bit land, as it sounds, you're realistically running out of address space already. Give us some more information and we can probably tell you a different way to approach your problem since explicitly representing hundreds of millions of objects in a map, or really any datastructure in memory, rarely makes sense.
|
# ? May 5, 2011 17:22 |
|
This is an interesting aspect of C++... it's mature enough that when you begin to approach its limits, in a "seems weird I have to think about stuff in this way" kind of way, the problem is effectively always on your end.
|
# ? May 5, 2011 17:54 |
|
You could use a hash_map, or an array (which would require changing logic of your program most likely a bit). That should reduce the amount of overall memory needed. And yea, you should explain your problem to us so we can suggest a better algorithm/data-structure. pr0metheus fucked around with this message at 18:07 on May 5, 2011 |
# ? May 5, 2011 18:01 |
|
I need to get the first three objects from a sequence but I don't have a random access iterator. I don't care what order I get them in.code:
2. Is there a better way?
|
# ? May 5, 2011 23:26 |
I don't think the behaviour of multiple uses of the ++ operator (either prefix or postfix) in a single statement is well-defined. I'd write a function that takes a non-const reference to your iterator, eats three items from it, and returns your plane.
|
|
# ? May 5, 2011 23:31 |
|
Hello, I have a program which compiles fine, but at the linking stage I get (several instances of) this error:code:
code:
To compile I'm using code:
|
# ? May 6, 2011 00:01 |
|
nielsm posted:I don't think the behaviour of multiple uses of the ++ operator (either prefix or postfix) in a single statement is well-defined. Doesn't the , operator make it a sequence point and therefore well defined? Edit: Ah, never mind, it's not actually a comma operator in this context: http://en.wikipedia.org/wiki/Sequence_point (see part 4) UraniumAnchor fucked around with this message at 00:17 on May 6, 2011 |
# ? May 6, 2011 00:14 |
|
UraniumAnchor posted:Doesn't the , operator make it a sequence point and therefore well defined? the "," in a function parameter list is not the , operator
|
# ? May 6, 2011 00:17 |
|
chiyosdad posted:Hello, I have a program which compiles fine, but at the linking stage I get (several instances of) this error:
|
# ? May 6, 2011 00:19 |
|
UraniumAnchor posted:Doesn't the , operator make it a sequence point and therefore well defined? Oh, yeah. quote:Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
|
# ? May 6, 2011 00:23 |
|
GrumpyDoctor posted:Are you trying to pass a const ofstream & somewhere? No. Is there a way to figure out where the "main.cpp:(.text+0x3502)" location refers to? Edit: that doesn't suck. Like I assume it means 0x3502 bytes or characters into the text file? There is no way to count that far... chiyosdad fucked around with this message at 00:34 on May 6, 2011 |
# ? May 6, 2011 00:30 |
|
Figure out what the base address of .text is (third column in readelf -s output), add it to 0x3502, run it through addr2line.
|
# ? May 6, 2011 00:37 |
|
pseudorandom name posted:Figure out what the base address of .text is (third column in readelf -s output), add it to 0x3502, run it through addr2line. I assume "output" means the .o output from the g++? I get something like this: Symbol table '.symtab' contains 10493 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS main.cpp 2: 0000000000000000 0 SECTION LOCAL DEFAULT 3419 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3421 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3422 5: 0000000000000000 0 SECTION LOCAL DEFAULT 3423 6: 0000000000000000 0 SECTION LOCAL DEFAULT 3425 7: 0000000000000000 0 SECTION LOCAL DEFAULT 3426 8: 0000000000000000 0 SECTION LOCAL DEFAULT 3427 9: 0000000000000000 0 SECTION LOCAL DEFAULT 3428 10: 0000000000000000 0 SECTION LOCAL DEFAULT 3429 11: 0000000000000000 0 SECTION LOCAL DEFAULT 3431 12: 0000000000000000 0 SECTION LOCAL DEFAULT 3433 13: 0000000000000000 0 SECTION LOCAL DEFAULT 3434 14: 0000000000000000 0 SECTION LOCAL DEFAULT 3435 15: 0000000000000000 0 SECTION LOCAL DEFAULT 3437 16: 0000000000000000 0 SECTION LOCAL DEFAULT 3439 17: 0000000000000090 1 OBJECT LOCAL DEFAULT 3422 _ZStL8__ioinit 18: 0000000000000000 0 SECTION LOCAL DEFAULT 3441 19: 0000000000000000 0 SECTION LOCAL DEFAULT 3442 ... I'm not sure what to do with this? I tried code:
code:
|
# ? May 6, 2011 00:54 |
|
Sorry, I meant readelf -S, not readelf -s.
|
# ? May 6, 2011 01:00 |
|
pseudorandom name posted:Sorry, I meant readelf -S, not readelf -s. Ok, thanks. So the output is code:
addr2line -f -e main.o 0x4FB4 main main.cpp:0 0x6834 + 0x3502 = 0x9D36 gives addr2line -f -e main.o 0x9D36 ?? ??:0 Lol...
|
# ? May 6, 2011 01:10 |
|
No, the address, which is 0. So 0x3502 is the actual address. Are you compiling with debugging symbols? You can't turn an address to a line number without them.
|
# ? May 6, 2011 01:36 |
|
How about passing one by value?
|
# ? May 6, 2011 01:40 |
|
That constructor (passing a std::string to std::ofstream) was added in C++0x, but the compiled libstdc++ library on your system does not actually support C++0x. Normally this doesn't matter for template classes (which std::ofstream secretly is) because the system will happily just emit it when you use it, but in this case there's an extern template declaration for std::ofstream which causes the compiler to believe that some external translation unit will provide symbols for all of its members. And indeed, there's a corresponding explicit instantiation of std::ofstream in the standard library, except that it (because it was compiled without '0x support) has no idea that it needs to provide that constructor, or even that that constructor exists. The minimal test case for this would be something like: code:
ETA: The fix is to either pass .c_str() to the ofstream constructor or install a standard library which matches your headers. rjmccall fucked around with this message at 02:53 on May 6, 2011 |
# ? May 6, 2011 02:50 |
|
rjmccall posted:That constructor (passing a std::string to std::ofstream) was added in C++0x, but the compiled libstdc++ library on your system does not actually support C++0x. Normally this doesn't matter for template classes (which std::ofstream secretly is) because the system will happily just emit it when you use it, but in this case there's an extern template declaration for std::ofstream which causes the compiler to believe that some external translation unit will provide symbols for all of its members. And indeed, there's a corresponding explicit instantiation of std::ofstream in the standard library, except that it (because it was compiled without '0x support) has no idea that it needs to provide that constructor, or even that that constructor exists. YESSS!!! That was exactly the problem! Thank you so much!!! I got it to work by ctrl+fing all instances of ofstream and putting in the .c_str(). Kind of amazing that that was the only problem given that the library is retarded.
|
# ? May 6, 2011 07:21 |
|
I've got a homework assignment that's driving me nuts. I'm implementing a compiler for a custom language that translates to C. This language supports nested functions that can reference variables in their parent functions. From what I understand, the best way to implement this is to pass a static link (a pointer to the stack frame of the enclosing function) to each function, from which you can find the variable you want by applying a constant offset. The problem I'm having is that I can't seem to figure out a way to consistently get the correct offset for a given variable. Here's a quick example: code:
First of all, am I on the right track with this? I'm not sure if using a pointer to the parent function's first parameter is the "proper" way to implement a static link. Second, how can I determine the offset of a given local variable from the static link at compile time? It'd be a heck of a lot easier if I knew exactly what a given function's stack frame looked like, but I'm not sure how to figure that out. A nudge in the right direction would be greatly appreciated.
|
# ? May 6, 2011 09:29 |
|
Gordon Cole posted:I've got a homework assignment that's driving me nuts. I'm implementing a compiler for a custom language that translates to C. This language supports nested functions that can reference variables in their parent functions. From what I understand, the best way to implement this is to pass a static link (a pointer to the stack frame of the enclosing function) to each function, from which you can find the variable you want by applying a constant offset. Just figure out which variables from the parent function are being used in the nested function and pass references/pointers to all of them when calling the nested function.
|
# ? May 6, 2011 14:52 |
|
Gordon Cole posted:First of all, am I on the right track with this? I'm not sure if using a pointer to the parent function's first parameter is the "proper" way to implement a static link. Second, how can I determine the offset of a given local variable from the static link at compile time? It'd be a heck of a lot easier if I knew exactly what a given function's stack frame looked like, but I'm not sure how to figure that out. You can't predict anything about the layout of stack variables. The compiler can (and will) place them in any order it feels like, sometimes combining multiple variables into a single stack slot or never allocating any stack space at all.
|
# ? May 6, 2011 15:03 |
|
You might wanna use a struct for each stack frame and pass pointers to that around.
|
# ? May 6, 2011 15:25 |
|
Out of curiosity, is there a reason that delete and delete[] both exist? Is it an efficiency thing?
|
# ? May 6, 2011 16:51 |
|
every delete must match the form of its new and doing otherwise results in undefined behaviour.code:
|
# ? May 6, 2011 17:09 |
|
Dicky B posted:every delete must match the form of its new and doing otherwise results in undefined behaviour. yeah, but that's up to the designers of c++. was there a reason it needed to be that way?
|
# ? May 6, 2011 17:10 |
|
tractor fanatic posted:yeah, but that's up to the designers of c++. was there a reason it needed to be that way? http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.13 Edit: Although I suppose that link doesn't exactly explain why this decision was made...
|
# ? May 6, 2011 17:15 |
|
code:
|
# ? May 6, 2011 17:19 |
|
But I'm not telling delete[] how many times to call the destructor; it already knows that magically. And like Dicky B said: you can't mix new[] with delete. I can't specifically choose to call the destructor on only the one element, so combining delete and delete[] into a single magical operator doesn't seem like it loses any expressive power.
|
# ? May 6, 2011 17:25 |
Paniolo posted:Consider what this program will output - in particular, how many times Foo's destructor will be called - and the design will make more sense. But why not just translate new Foo to new Foo[1] in the compiler and only have operator new[], completely scrapping the non-array operator new? And the same with operator delete. As far as I know, there isn't any practical difference between allocating an array of a single element and just allocating a single instance. tractor fanatic posted:But I'm not telling delete[] how many times to call the destructor; it already knows that magically. And like Dicky B said: you can't mix new[] with delete. I can't specifically choose to call the destructor on only the one element, so combining delete and delete[] into a single magical operator doesn't seem like it loses any expressive power. But what if the library allocates from different pools depending on whether you use the regular or array operator new?
|
|
# ? May 6, 2011 17:26 |
|
That Turkey Story posted:Yes, you can put an instance of any type on the stack in C++ (of course, that type itself might internally allocate memory on the free store if it wants, i.e. an std::map or std::string). pr0metheus posted:You could use a hash_map, or an array (which would require changing logic of your program most likely a bit). That should reduce the amount of overall memory needed. Normally I'd be really happy to explain all the details of a project like this, but the main goal of the program is research (I'm looking to publish, based on ~4 months of work), so it seems like a bad idea to post it all on the internet before I'm finished. I could cut out the over-arching explanation, but then I wouldn't be able to explain the justification of the engineering well. I know it probably sounds like I don't know what I'm talking about (I'm kind of rusty in C), but a single large object is unavoidable in this application (and I'd normally scoff at this too). Thanks for your help - I'll come back and tell the whole story if you're still interested when the paper's out.
|
# ? May 6, 2011 17:26 |
|
nielsm posted:But what if the library allocates from different pools depending on whether you use the regular or array operator new? Do you mean as a result of an overload, or as a result of the way the system manages the memory?
|
# ? May 6, 2011 17:32 |
|
|
# ? Apr 28, 2024 20:28 |
|
nielsm posted:But why not just translate new Foo to new Foo[1] in the compiler and only have operator new[], completely scrapping the non-array operator new? And the same with operator delete. There's no difference in layout, if that's what you mean. There's a difference in semantics at deletion time, where deleting a single object can require a virtual destructor to be called but deleting an array cannot, but again that's directed by the core division. The reason for that division is efficiency and simplicity. While the committee doesn't guarantee that the standard allocation functions will be implemented in terms of malloc and free, it does want to permit that, which would not be possible if the platform ABI required separate memory pools for single-object allocations vs. array allocations. And if the platform ABI doesn't require that, then it's basically forced to allocate extra memory with every single (non-POD) heap allocation.
|
# ? May 6, 2011 17:38 |