Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
hooah
Feb 6, 2006
WTF?
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:
void increase (void* data, int psize)
{
  if ( psize == sizeof(char) )
  { char* pchar; pchar=(char*)data; ++(*pchar); }
  else if (psize == sizeof(int) )
  { int* pint; pint=(int*)data; ++(*pint); }
}
I haven't run across the (char*)data construction before on this website or elsewhere, so I don't know what's going on. Could anyone give an explanation, please?

Adbot
ADBOT LOVES YOU

Posting Principle
Dec 10, 2011

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

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

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:
code:
void increase (void* data, int psize)
{
  if ( psize == sizeof(char) )
  { char* pchar; pchar=(char*)data; ++(*pchar); }
  else if (psize == sizeof(int) )
  { int* pint; pint=(int*)data; ++(*pint); }
}
I haven't run across the (char*)data construction before on this website or elsewhere, so I don't know what's going on. Could anyone give an explanation, please?

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:
void increase (void* data, int psize)
{
  if (psize == sizeof(char))
  {
    char* pchar;
    pchar=(char*)data;
    ++(*pchar);
  }
  else if (psize == sizeof(int))
  {
    int* pint;
    pint=(int*)data;
    ++(*pint);
  }
}
Secondly, if it's plain C you don't need the cast, and if it's C++, templates
would be a better choice, though I assume they're coming later in the tutorial.

Third, you don't need the intermediate variables

code:
void increase (void* data, int psize)
{
  if (psize == sizeof(char))
  {
    ++(*((char*)data));
  }
  else if (psize == sizeof(int))
  {
    ++(*((int*)data));
  }
}
Fourthly, the size is not enough information to know the type.
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

hooah
Feb 6, 2006
WTF?
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.

shrughes
Oct 11, 2008

(call/cc call/cc)

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

ephphatha
Dec 18, 2009





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.

shrughes
Oct 11, 2008

(call/cc call/cc)
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.

Rottbott
Jul 27, 2006
DMC
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.

That Turkey Story
Mar 30, 2003

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.

Volte
Oct 4, 2004

woosh woosh

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.
The thing you quoted literally says that size_t is used for counts, so how does it make anything clearer? 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.

hooah
Feb 6, 2006
WTF?
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.

That Turkey Story
Mar 30, 2003

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.

astr0man
Feb 21, 2007

hollyeo deuroga

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

nielsm
Jun 1, 2009



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.

Grocer Goodwill
Jul 17, 2003

Not just one kind of bread, but a whole variety.

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

Volte
Oct 4, 2004

woosh woosh

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

unixbeard
Dec 29, 2004

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

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
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!

Harvey Mantaco
Mar 6, 2007

Someone please help me find my keys =(
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:
this->_levelCamera = new LevelCamera();

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:
LevelCamera::LevelCamera()  : _startTime(0.0f), _endTime(0.0f), _timeDiff(0.0f), _velMul(0.0f){
    _isDragging = false;
    _isFingerMoved = false;
    _isAnimationEnabled = false;
    _activatedEvent = false;
    _isSwallowTouches = true;
    CCSize winSize = CCDirector::sharedDirector()->getWinSize();
    
    CCRect r = CCRectMake(0, 0, winSize.width, winSize.height);
    _areaHeight = r.size.height;
    _areawidth = r.size.width;
    _orientation = CCItemsScrollerHorizontal;
    
	//At this point a CCLog shows everything has been set properly

    _lastPos = CCPoint(0, 0);
    _velPos = CCPoint(0, 0);
    _clickedPoint = CCPoint(0, 0);
    _distMov = CCPoint(0, 0);
    _prevMovPos = CCPoint(0, 0);
}

Harvey Mantaco fucked around with this message at 19:39 on Aug 11, 2013

raminasi
Jan 25, 2005

a last drink with no ice
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.

Harvey Mantaco
Mar 6, 2007

Someone please help me find my keys =(

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:
#ifndef __Shard__LevelCamera__
#define __Shard__LevelCamera__

#include "Shard.h"
class Level;

#endif 
class LevelCamera : CCObject
{
private:
    typedef LevelCamera self;
    
    typedef enum{
        CCItemsScrollerVertical,
        CCItemsScrollerHorizontal
    } CCItemsScrollerOrientations;
    
    CC_SYNTHESIZE(CCItemsScrollerOrientations, _orientation, Orientation);
    CC_SYNTHESIZE(CCFloat, _timeDiff, TimeDiff);
    CC_SYNTHESIZE(CCFloat, _startTime, StartTime);
    CC_SYNTHESIZE(CCFloat, _endTime, EndTime);
    CC_SYNTHESIZE(CCFloat, _velMul, VelMul);
    CC_SYNTHESIZE(bool, _isSwallowTouches, IsSwallowTouches);

    int _originX;
    int _originY;
    int _areawidth;
    int _areaHeight;
    CCPoint _startSwipe;
    CCPoint _offset;
    CCSize _itemSize;
    bool _isDragging;
    bool _isFingerMoved;
    bool _isAnimationEnabled;
    CCPoint _lastPos;
    CCPoint _velPos;
    CCPoint _clickedPoint; //location of touch begin/mouse down event
    CCPoint _distMov;
    CCPoint _prevMovPos;
    bool _activatedEvent;
    bool inSelectableArea(CCPoint point);
    
    float getTimeTick();
    
public:
    LevelCamera();
    ~LevelCamera();
    
    void setupSelectableArea(CCRect r);
    bool ccTouchBeganHandler(CCTouch *pTouch, CCEvent *pEvent, Level *level);
    void ccTouchMovedHandler(CCTouch *pTouch, CCEvent *pEvent, Level *level);
    void ccTouchEndedHandler(CCTouch *pTouch, CCEvent *pEvent, Level *level);
    void updateHandler(float dt, Level *level);
};
I know I'm declaring things in a random way that isn't consistent but I was testing out the different ways to declare things and how they work, I'm still really new to this.

Surrounding that first one:
code:
void Level::initializeTouchHandling()
{
    this->_levelCamera = new LevelCamera();
    this->scheduleUpdate();
    this->setTouchEnabled(true);
    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true); 
}
:coupons: EDIT :coupons:
-------
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

-Blackadder-
Jan 2, 2007

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

OzyMandrill
Aug 12, 2013

Look upon my words
and despair

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.

That Turkey Story
Mar 30, 2003

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.

OzyMandrill
Aug 12, 2013

Look upon my words
and despair

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

Volguus
Mar 3, 2009
Has anyone ever used libunrar (from https://github.com/vilkov/libunrar)?

I have the following code:

code:
extractor_service::extract_status unrar_extractor_service::extract(const boost::filesystem::path& destination, 
				 const std::set< boost::filesystem::path >& files, 
				 std::set< boost::filesystem::path >& extractedFiles)
{
  modif_string dest_str(destination.c_str(),destination.string().length());
  Logger logger = Logger::getInstance("log");
  for(auto& file : files )
  {
    RAROpenArchiveDataEx rarData = {0};    
    modif_string str(file.c_str(),file.string().length());
    rarData.ArcName = str.str();
    rarData.OpenMode = RAR_OM_EXTRACT;    
    HANDLE archive = RAROpenArchiveEx(&rarData);
    if(rarData.OpenResult != 0) {
      RARCloseArchive(archive);
      continue;
    }
    //RARSetCallback(archive,RARCallbackProc,0);
      RARHeaderDataEx rarHeader;
      if(RARReadHeaderEx(archive,&rarHeader) != 0) {
	continue;
      }      
      
      if(RARProcessFile(archive,  RAR_EXTRACT, dest_str.str() , NULL) != 0)
      {
	LOG4CPLUS_ERROR(logger, "Cannot extract "<<file.string());
      }
      else
      {
	LOG4CPLUS_INFO(logger, "Successfully extracted "<<file.string());
      }
      

    RARCloseArchive(archive);
  }
  return extractor_service::extrOK;
}
where modif_string is a struct like this (shouldnt matter in this context):
code:
struct modif_string {
  modif_string(const char* str, size_t len):value(new char[len+1]){ 
    memset(value, 0, len+1);
    if(str && len>0) {
      strncpy(value,str,len);
    }
    
  }
  char* str() const {
    return value; 
  }
  ~modif_string(){    
    delete []value;    
  }
private:
  char* value;
};
As it can be seen, I am passing to the function a set of files and a destination directory. I am expecting back the list of files that were extracted (the set of files will contain text files, pictures, junk, and hopefully some rar files).
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
But there's nothing in the destination folder. I tried with a callback function, without, and everything i could think of. What would I need to do to be able to extract a multi-volume rar archive?

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

hooah
Feb 6, 2006
WTF?
Why would the following code not print anything to the console?
code:
int main()
{
	list<int> randoms;
	list<int>::iterator i;
	int random;

	for(i=randoms.begin(); i!=randoms.end(); i++)
	{
		random=rand()%1000;
		randoms.push_back(random);
	}
	for(i=randoms.begin(); i!=randoms.end(); i++)
		cout << (*i) << endl;
	return 0;
}

raminasi
Jan 25, 2005

a last drink with no ice
How many numbers are you expecting it to print?

hooah
Feb 6, 2006
WTF?

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

chglcu
May 17, 2007

I'm so bored with the USA.

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.

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

prolecat posted:

Can't remember if list iterators are guaranteed to be valid after adding elements to the list.
std::list iterators are only invalidated when you remove the item they're pointing at from the list, and if that property isn't required for what you're doing you almost certainly shouldn't be using std::list.

Posting Principle
Dec 10, 2011

by Ralp
Why even use a list? If you want to write numbers to stdout, just write them to stdout.

C++ code:
generate_n(ostream_iterator<int>(cout, "\n"),
           1000,
           bind(uniform_int_distribution<>(0,999), default_random_engine{}));

Harik
Sep 9, 2001

From the hard streets of Moscow
First dog to touch the stars


Plaster Town Cop
code:
    for(auto i : randoms)
        cout << i << endl;
The new for(foo : bar) construct is so much nicer for this kind of thing. Added in C++11, so hopefully your compiler supports it already. If you want to modify the container in-place, you can use
code:
    for(auto &i : randoms)
        i++;

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; ?

Posting Principle
Dec 10, 2011

by Ralp

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.

raminasi
Jan 25, 2005

a last drink with no ice

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

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Posting Principle posted:

Reads easier, easier to refactor, doesn't use endl, avoids the off by one trap.
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.
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

Posting Principle
Dec 10, 2011

by Ralp

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.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
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.

OzyMandrill
Aug 12, 2013

Look upon my words
and despair

hooah posted:

Why would the following code not print anything to the console?
code:
int main()
{
	list<int> randoms;
	list<int>::iterator i;
	int random;

	for(i=randoms.begin(); i!=randoms.end(); i++)
	{
		random=rand()%1000;
		randoms.push_back(random);
	}
	for(i=randoms.begin(); i!=randoms.end(); i++)
		cout << (*i) << endl;
	return 0;
}

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:
randoms[i] = random;
in the loop, and now you are not changing the value of end() each time.

As with most things, there are 100 different ways to code this in C++ ;)

Adbot
ADBOT LOVES YOU

nielsm
Jun 1, 2009



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.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply