|
Between my summer class and fall classes, I'm trying to do some more C++ learning on my own. Reading through the tutorial on cplusplus.com, I'm getting confused by void pointers. Particularly, this portion of the example code:code:
|
# ? Aug 7, 2013 15:01 |
|
|
# ? Jun 7, 2024 22:16 |
|
Its casting data from a void* to a char*, converting the expression from one type to another. The syntax being used is a c-style cast. Take a look at this for examples of c-style and c++ style casting. If you're doing c++, you should prefer to use c++ casts when possible.
|
# ? Aug 7, 2013 15:05 |
|
hooah posted:Between my summer class and fall classes, I'm trying to do some more C++ learning on my own. Reading through the tutorial on cplusplus.com, I'm getting confused by void pointers. Particularly, this portion of the example code: I'm not surprised you're confused by this awful code. First of all, the formatting is dire. If you're going to have those variables it should be laid out more like this: code:
would be a better choice, though I assume they're coming later in the tutorial. Third, you don't need the intermediate variables code:
Incrementing a floating point number is a very different operation to incrementing an integer, and on hardware you usually care about, sizeof(int) == sizeof(float). Fifthly, there are cpu architectures where the memory alignment matters, so if you tried to increment an integer stored in a memory address that wasn't a multiple of 4, crazy things happen. And just to top it all of, psize should be a size_t
|
# ? Aug 7, 2013 22:41 |
|
Thanks for the replies. Where else would be a good but not super in-depth description of pointers and dynamic memory? I've read some from my book from the summer class and watched a video on the heap, but it's not sticking very well. And this whole typecasting thing is new, as well.
|
# ? Aug 8, 2013 02:28 |
|
Edison was a dick posted:And just to top it all of, psize should be a size_t Why? The only valid values are sizeof(char) and sizeof(int).
|
# ? Aug 8, 2013 07:08 |
|
It makes it clearer that the second parameter is used as a size, not a count. Plus the whole sizeof returning a size_t thing.
|
# ? Aug 8, 2013 07:20 |
|
I know what size_t is. But here, the value is either a 1 or a 4. Or an 8 on some systems. There's no way you can say that parameter has to be a size_t. int can contain a count.
|
# ? Aug 8, 2013 08:19 |
|
Unless you extend it later to work on other types. It's clearly supposed to be somewhat 'generic', albeit not in a good or useful way.
|
# ? Aug 8, 2013 08:48 |
|
shrughes posted:Why? The only valid values are sizeof(char) and sizeof(int). I don't see that documented, though I'm too lazy to look up the lovely tutorial this was pulled from. Seems more like other sizes are valid as input to the function but just result in no operation being performed. Can't really know without documentation. The example is still poo poo, though.
|
# ? Aug 8, 2013 16:31 |
|
Ephphatha posted:It makes it clearer that the second parameter is used as a size, not a count. Plus the whole sizeof returning a size_t thing.
|
# ? Aug 8, 2013 19:58 |
|
Uhhh, guys?hooah posted:Thanks for the replies. Where else would be a good but not super in-depth description of pointers and dynamic memory? I've read some from my book from the summer class and watched a video on the heap, but it's not sticking very well. And this whole typecasting thing is new, as well.
|
# ? Aug 8, 2013 20:26 |
|
Volte posted:sizeof does not return a size_t because a size_t is not a type, it's a typedef. It's literally equivalent to whatever the underlying type is. If you replace int with size_t you are gaining nothing and losing nothing. I'm not sure you get typedefs, Volte.
|
# ? Aug 8, 2013 20:30 |
|
hooah posted:Uhhh, guys? The K&R C book? edit: The K&R book will explain pointers, but as far as learning how memory management actually works you should take an operating systems class or something I guess. astr0man fucked around with this message at 20:40 on Aug 8, 2013 |
# ? Aug 8, 2013 20:36 |
hooah posted:Uhhh, guys? Pointers and memory (in particular in flat virtual memory models as a user space application) are really, simple, even though they can cause some complex behaviour, mainly when you begin involving a memory manager. Management of memory on an OS level, including managing virtual memory on the CPU and such, is complicated, but if you aren't writing an OS or working on an embedded system you don't really need that for most purposes. A short-ish version: You have a gigantic series of bytes in a parricular order, that's the machine's memory. Each position in memory has a unique address, when you work with such an address in a programming language it's called a pointer. In C there's pointers to specific types and pointers to "void", ignore void pointers right now. The pointer being to a specific type is only a concept that exists in the source code you write, it's not something inherent of the address, after all the address is just a number identifying a specific location in memory. The pointed-to type of a pointer tells the compiler what code is should generate to handle the data when you try to access whatever the pointer points at. If it's a char pointer the compiler will produce code to load a single byte at the position and work with that, if it's an int pointer it might generate code to load 4 bytes from that position (and the following 3) and work with that, if it's a pointer to a struct and you access some field in that you will get code to offset the pointer to the field's relative location and then work with the data type of the field. The pointer is just a number, the type you tell the compiler it points to determines how your program will treat the pointed-to data. So type casting between pointer types is telling the compiler to treat the pointed-to data differently when you access it. And a void pointer is a pointer where you haven't told the compiler what kind of data is being pointed to so you must case the pointer to a specific type before you can dereference it. Memory management (in C, mainly the malloc/calloc/realloc/free functions, in C++ the new and delete operators) is from a usage point of view just asking to get a contiguous range of memory that's guaranteed to not be in use by something else. Now if you produce pointers that would reference data outside an allocated block, or crossing the bounds between two blocks, you have undefined behaviour, and that's how you get the complexity from simple rules: A huge class of potential programmer errors. But it's simple. Really. Just weird to explain.
|
|
# ? Aug 8, 2013 21:18 |
|
Volte posted:If you replace int with size_t you are gaining nothing and losing nothing. Well, you do lose quite a few bugs in your 64-bit build. But 4 gigs ought to be enough for anybody...
|
# ? Aug 10, 2013 22:22 |
|
Grocer Goodwill posted:Well, you do lose quite a few bugs in your 64-bit build. But 4 gigs ought to be enough for anybody...
|
# ? Aug 10, 2013 22:37 |
|
Volte posted:The int in question contains a number between 1 and 8, I don't know of any compiler whose int type is less than 4 bits. I thought an int is guaranteed to always be at least 16 bits
|
# ? Aug 11, 2013 05:11 |
|
In other words you're wasting a lot of unnecessary stack space. What you should do is define an enumeration with three elements, and give it an implicit conversion operator that converts 1 to SIZEOF_CHAR, sizeof(int) to SIZEOF_INT, and anything else to INVALID. That way the API of the function is clearly expressed, and no-one gets the mistaken impression that they can pass sizeof(long) to it and have it do something meaningful. Or, since this function is almost always going to be called with a compile-time constant as the second parameter, use a templated function with template specializations for the 1 and sizeof(int) cases. That way, you don't need to have code for the sizeof(int) case at all when you're compiling for a system where sizeof(int) == 1!
|
# ? Aug 11, 2013 05:51 |
|
I'm new to C++ and currently working in Cocos2d-x. I'm having an issue where I'm creating an object and when I go to use it, it has forgotten all of the values I've initialized it with. For example: I have a LevelCamera object where I have a bunch of simple int's, CCPoint's and CCSize's under private: in the header file, and in the LevelCamera() implementation I am setting them to whatever. In the implementation I CCLog the values back to the screen and everything seems fine. However, in my update that runs the game logic it is calling the LevelCamera object I created using code:
and all the int's have been set to 0, or some other completely off number. What is going on? I'm not sure what to even post from my code. My implementation: code:
Harvey Mantaco fucked around with this message at 19:39 on Aug 11, 2013 |
# ? Aug 11, 2013 19:37 |
|
Post the LevelCamera class definition (where you declare all the member variables) too. And the lines surrounding the first one you posted probably wouldn't hurt.
|
# ? Aug 11, 2013 19:40 |
|
GrumpyDoctor posted:Post the LevelCamera class definition (where you declare all the member variables) too. And the lines surrounding the first one you posted probably wouldn't hurt. code:
Surrounding that first one: code:
------- I was autoreleasing the object too soon. Christ, I need to sit down with my memory management chapter again. It starts out about how managing your own objects and memory is just like switching to a standard from an automatic but last time I drove stick I wrapped it around a tree so gently caress whatever. ------- Harvey Mantaco fucked around with this message at 20:39 on Aug 11, 2013 |
# ? Aug 11, 2013 19:48 |
|
This is more of a general question. I saw the book recommendations mentioned in the OP but I'm looking for something specific. Basically I'm looking for textbooks that are used for Introduction to Computer Science. Programming: Principles and Practice using C++ by Bjarne Stroustrup was recommended to me because in addition to teaching you C++ it's supposed to be a good intro to cs as well. Is this a good textbook to go with for self-study? Or are there other good "Intro to Computer Science with C++" type books I should check out also?
-Blackadder- fucked around with this message at 01:50 on Aug 12, 2013 |
# ? Aug 12, 2013 01:30 |
|
I always found Stroustrup to be a bit tough going... I can't really recommend the book I first learnt C++ with, partly because I can't remember what it was, but mostly because I found I only used the first third of the book and then I had enough to get going. However, Newnes pocket C++ has been my absolute favourite reference. V. concise & simple explanations with neat examples, still use it now. I ended up with it as during my early C++ years (before Google existed!) I needed to check some obscure behavior, so looked at all the available books in my local bookshop & this was the only one that told me what I wanted to know.
|
# ? Aug 12, 2013 15:07 |
|
OzyMandrill posted:However, Newnes pocket C++ has been my absolute favourite reference. V. concise & simple explanations with neat examples, still use it now. Don't use this. It's from 1995 and the first C++ standard wasn't until 1998. There is going to be a lot that is incorrect and a lot of important stuff that is left out.
|
# ? Aug 12, 2013 15:11 |
|
That Turkey Story posted:Don't use this. It's from 1995 and the first C++ standard wasn't until 1998. There is going to be a lot that is incorrect and a lot of important stuff that is left out. I honestly thought it was an up to date version. I guess they haven't redone it as noone but me used it. Sorry! Wow.. that makes me feel really old & sad...
|
# ? Aug 12, 2013 15:55 |
|
Has anyone ever used libunrar (from https://github.com/vilkov/libunrar)? I have the following code: code:
code:
Now, when I call this function with a simple rar file everything is fine and the file is extracted in the specified directory. When I call this function on a multi-volume archive, I get something like this: pre:Cannot extract /tmp/test/test.r00 Cannot extract /tmp/test/test.r01 Cannot extract /tmp/test/test.r02 Cannot extract /tmp/test/test.r03 Successfully extracted /tmp/test/test.rar Thank you. Edit: Im using gcc (GCC) 4.8.1 20130603 (Red Hat 4.8.1-1) on Fedora 19 if that matters. Volguus fucked around with this message at 02:17 on Aug 13, 2013 |
# ? Aug 13, 2013 02:07 |
|
Why would the following code not print anything to the console?code:
|
# ? Aug 13, 2013 03:05 |
|
How many numbers are you expecting it to print?
|
# ? Aug 13, 2013 03:12 |
|
GrumpyDoctor posted:How many numbers are you expecting it to print? I was going to say zero, but now that I look at it, I didn't change enough when I changed to using an iterator. However, I just tried changing the initialization of the list to "list<int> randoms(1000, 0);", and now it just shows a long blank screen with the cursor at the top; it doesn't get to the "Press any key to continue..."
|
# ? Aug 13, 2013 03:24 |
|
hooah posted:I was going to say zero, but now that I look at it, I didn't change enough when I changed to using an iterator. However, I just tried changing the initialization of the list to "list<int> randoms(1000, 0);", and now it just shows a long blank screen with the cursor at the top; it doesn't get to the "Press any key to continue..." The first version would print nothing due to the first loop iterating over an empty list. In the second version, using push_back() will add an item to the end of the list. In that case, you'll never reach randoms.end() since your iterator will always be 1000 items behind, if i is even valid at after the first push_back(). Can't remember if list iterators are guaranteed to be valid after adding elements to the list.
|
# ? Aug 13, 2013 03:53 |
|
prolecat posted:Can't remember if list iterators are guaranteed to be valid after adding elements to the list.
|
# ? Aug 13, 2013 04:43 |
|
Why even use a list? If you want to write numbers to stdout, just write them to stdout.C++ code:
|
# ? Aug 13, 2013 05:34 |
|
code:
code:
Posting Principle posted:Why even use a list? If you want to write numbers to stdout, just write them to stdout. I would guess because he wants an array of random numbers for something else and printing them out is the easiest way to see if it works like expected. Also because that's... yeah. Why that way instead of the standard tutorial for(...) cout << random()%1000 << endl; ?
|
# ? Aug 13, 2013 06:00 |
|
Harik posted:I would guess because he wants an array of random numbers for something else and printing them out is the easiest way to see if it works like expected. Also because that's... yeah. Why that way instead of the standard tutorial for(...) cout << random()%1000 << endl; ? Reads easier, easier to refactor, doesn't use endl, avoids the off by one trap.
|
# ? Aug 13, 2013 06:17 |
|
Posting Principle posted:Reads easier, easier to refactor, doesn't use endl, avoids the off by one trap. It does not read any easier if you're at the level where you're struggling with basic "iteration over a container." (And you can avoid std::endl just as easily in a for loop as your code does.)
|
# ? Aug 13, 2013 06:31 |
|
Posting Principle posted:Reads easier, easier to refactor, doesn't use endl, avoids the off by one trap. Surely endl is better than "\n"? "\n" is only slightly better than a magic number. Avoids the off by one trap by having both "1000" and "999" appearing as magic numbers embedded in the code? Hm. (Edit: Okay, they're for different things, I'll grant that one is actually valid. I too enjoy a random integer function that takes upper and lower values inclusive as parameters.) Are you sure you aren't just trolling with deliberate obfuscation? Edit2: Hell, even knowing what all those functions do, that is not very readable at all. It's not intuitive to see which parameters belong to what, and the parameter orders are non-obvious in the first place, so to read it easily you have to not only be familiar with all the functions but also have correctly memorized the order of their parameters and be familiar with the layout foibles of the coder. This "splitting a single function call across three lines because otherwise it would be even less readable" paradigm does not appeal to me. And in the end that code is longer, characters-wise, than doing the same thing in C would be. roomforthetuna fucked around with this message at 06:56 on Aug 13, 2013 |
# ? Aug 13, 2013 06:42 |
|
roomforthetuna posted:Ha ha. "Reads easier" like a fox! Maybe if all you've ever eaten is crazy modern C++ and you've never touched any other programming language. STL is over a decade old. You should probably catch up. quote:Avoids the off by one trap by having both "1000" and "999" appearing as magic numbers embedded in the code? Hm. Avoids two traps actually. generate_n generates n elements, where n is clearly stated instead of buried in a half open range. uniform_int_distribution specifies an exact closed range, instead of obfuscating the range behind a mod operator. quote:Are you sure you aren't just trolling with deliberate obfuscation? If you think that's obfuscated then I don't know what to say. It may not be appropriate for an absolute beginner, but it states the actual problem in a much more direct way than a solution involving std::lists and loops.
|
# ? Aug 13, 2013 06:59 |
|
Closed ranges are horrid, half-open ranges are the way to go pretty much any time you have a choice. There's a reason array indexes start at 0 and go up to length - 1.
|
# ? Aug 13, 2013 07:10 |
|
hooah posted:Why would the following code not print anything to the console? In both cases, the problem is at the for() Case 1: The list is empty, so randoms.end() returns 0, and i is also 0, so it skips the loop entirely. At the print line, the list is empty still so it outputs nothing. To fix this, make the end condition 'i<1000' so the loop depends on how many entries you want. Case 2: Initialising the list to have 1000 entries It will go into the loop this time (end() returns 1000 initially) BUT, each iteration causes it to APPEND a random number (so the list is now 1000 zeros followed by a random number) After 1 loop, end() now returns 1001, but i = 1 After 2 loop, end() returns 1002, i = 2 etc. Infinite loop! To fix case 2, just use: code:
As with most things, there are 100 different ways to code this in C++
|
# ? Aug 13, 2013 09:26 |
|
|
# ? Jun 7, 2024 22:16 |
OzyMandrill posted:It will go into the loop this time (end() returns 1000 initially) What, no. container.end() returns an iterator object for the container, specifically the one-past-end iterator. The assignment of an iterator to a plain int shouldn't even be possible, it should give a compilation error.
|
|
# ? Aug 13, 2013 09:56 |