   Problem making a new variable in a derived class.
  I'm not quite sure what the problem here is. Maybe someone can help me out.So... When I include this STRUCT in a .h file, it compiles fine:struct PBULLET_01 : public PARTICLE{PBULLET_01() {// initialize stuff here/// }void run_particle(float seconds){// do stuff here}  };However, when I change it to this, ti compiles fine, but performs a program error:struct PBULLET_01 : public PARTICLE{int something;PBULLET_01() {// initialize stuff here/// }void run_particle(float seconds){// do stuff here}  };The problem is that "int something;". The questions are: Why, and how do I fix it?It doesn't perform any errors when I access it normally, but when I try to run the internal function "pbullet.run_particle(time)", that is where the program performs the error. Any ideas?   
  What do you mean by 'performs an error'? Are you referring to a run-time error of some sort? What error message are you getting?Behavior that changes based on the presence or absence of specific variables is often an indication of undefined behavior somewhere in your program. I don't think there's enough info in your post to speculate as to where though.You can use [source] tags to format your code properly, which will make it easier for us to read. Also, although there are few actual 'rules' regarding naming style, it's pretty common to use all caps only for macros and constants; as such, using all caps for your class names will probably be a bit confusing (or at least distracting) to many programmers.   ;  It's a typical, "this program has performed an illegal operation-type error that varies from system to system. In this case, the Visual Studio Just-In-Time Debugger saying "An unhandled win32 exception has occurred in whatever.exe"When I use the debugger, it breaks to the point I called the function in the STRUCT. It is an update function, and the instances of the class are defined as an array within another management class that is passes between modules in the program. The exact line where the error occurs is:sc->pbullet.run_particle(time/1000.0f);Where "sc" is a class that has an array of PBULLET_01 objects "PBULLET_01 pbullet[128];". I can define variables beforehand from the derived class "sc->pbullet[42].x = 2" without causing an error. Likewise, I can stiff use that function fine, until I try to define a variable within the class "int something;". Also, "int something" has not been defined previously.   ;  These are all fairly obvious questions, but I'll ask anyway, just in case:1. Are you sure that sc is valid (non-null and referencing a valid object) every time you dereference it?2. What is the type of pbullet?3. If it's a raw array, are you sure you've allocated memory for it prior to accessing its elements?4. Are you sure that you're never reading or writing past the end of the array?These sorts of mistakes can often lead to unpredictable and inconsistent behaviors, so even if it works sometimes or in some cases it doesn't necessarily mean that the code is correct.   ;  1. "sc" is valid. As I said, as long as I don't add the varible in the derived class, I can use everything fine. The functions and all variable access works fine until I add a varible. Likewise, even if I don't try to the use "something" variable in any way, it still performs an error once the function is called. I can initialize "something" and access itex:sc->pbullet[0].something = 42;cout << sc->pbullet[0].something;output: 422. The type of pbullet[] is PBULLET_01 which is derived from PARTICLE (public)struct PBULLET_01 : public PARTICLE{}3 & 4. The array elements are defined by a static const that is used for looping:ex:static const int arraySize;int theArray[arraySize];So when I lop through an array it would be done like:for(int i = 0; i<arraySize; i++){cout << theArray << endl;}Likewise, as I said, it works before I add the extra variable. I have no problem running that line, and it all works properly. However, it crashes after I add that line. --------I tried to recreate the error in a more simplistic program like this:#include <iostream>#include <string>using namespace std;struct base{int valueA;virtual void print(){cout << "Derived Class: " << valueA << endl;}};struct derived: public base{int valueB;void print(){cout << "Derived Class: " << valueA << ", " << valueB << endl;}};int main(){static const int arraySize = 8;base varA[arraySize];derived varB[arraySize];varA[0].valueA = 1;varB[0].valueA = 2;varB[0].valueB = 3;varA[0].print();varB[0].print();return 0;}And that works fine.--------What is really weird is that I run it like this:for(int i = 0; i < sc->max_pbullets; i++){sc->pbullet.run_particle(time/1000.0f);}And that messes up. If I run it without "int something;" in the STRUCT, it works.(sc->max_pbullets is a static const int with a value of 128)However, if I try to use:for(int i = 0; i < 127; i++){sc->pbullet.run_particle(time/1000.0f);}or any other value between 0 and 47, it run. The problem is, it only actually runs run_particle() for pbullet[0], no other, and any number over 47 crashes. I can also just change max_pbullets to 47, or lower, and it still does that "half-working" thing.   ;  In your example you mentioned arraySize, but you didn't specify its value. Does it have the same value as max_pbullets? Actually, it would probably help if you were to post the complete code (rather than just examples and excerpts).One thing I don't seem to be communicating clearly is that just because the program works under certain conditions doesn't mean the code is correct. I really can't stress this enough: the fact that your program stops working when you add that variable is a very strong indicator of undefined behavior somewhere in your program.Here are a few suggestions:1. Use a container class such as std::vector or boost::array rather than using raw arrays. This has two significant advantages in this context: a) you don't have to track the size separately, which will reduce the potential for error when iterating over the container, and b) you can take advantage of bounds checking, thereby ensuring that you're not writing or reading past the end of the array.2. Be sure to assert that sc is non-null before every dereference. This won't catch invalid references, but it will at least provide a first line of defense against other errors.3. Make sure you know what's going on with sc ownership-wise. Is it created dynamically? If so, does it really need to be? If not, does it really need to be passed by pointer?Really, I think we'll need to see some more code at this point (unless the error is there and I just missed it).   ;  Post the minimum complete code that reproduces the issue. Of interest are how and where sc is created, and where its pbullet array is created and populated.Edit: also of interest is what iteration of the loop it crashes on, and what your debugger says is in the pbullet array at that index.   ;  I didn't use a vector or some other such container so that the memory was a set size, and that it saves speed by not being allocated dynamically. The program keeps track of quite a few things at once, and sorting a dynamic array tends to hurt the overall performance.sc is not null. It is not dynamically allocated. It is static, and defined at the beginning of the program loop. The purpose is to serve as a resource container. Pretty much every module needs to have access to all resources, so it it defined statically at the beginning, then passes as a reference to the other modules. "sc" is of type "SCENE", but I usually truncate it when passed to various functions so I don't have to write out a longer name each time. It gets fairly tedious having test conditions like:if((sc->ebullet.radius + sc->focus.radius) * (sc->ebullet.radius + sc->focus.radius) > distance_squared(sc->ebullet.position.x, sc->ebullet.position.z, sc->focus.position.x, sc->focus.position.z)){}just to test a 2d collision, let along if the names were longer. ex:struct SCENE{GMODE gMode;//OBJECT object[1024];FOCUS focus;static const int max_pbullets = 128;PBULLET_01 pbullet[max_pbullets];static const int max_ebullets = 1024;EBULLET_01 ebullet[max_ebullets];};"arraySize" isn't in the actual program. It was just an example of the way it is set up. Instead each array has its own static const int variable, such as "max_pbullets" and "max_ebullets". Likewise, there are a lot of inherited classes. For instance, OBJECT defines an object with a position. PARTICLE : public OBJECT sets up a particle system. PARTICLE_EMITTER : public OBJECT is similar. PBULLET_01 and EBULLET_01 are specialized particles that are derived from PARTICLE, and handle themselves instead of being defined by an emitter. The big reason that I'm not posting more code is that there is a ton of it. I'd have to do tons of clean-up just to make it readable, and it would still be far too long for posting. As for what iteration of the loop it crashes on, it crashes on the first iteration, unless the variable isn't present in the PBULLET_01 class. As for checking for null values, "sc" is initially defined, then all values contained within are defined at least as some default. From there, it has a checking function that loops through everything to make sure it IS all defined, or it throws an error. That function can be run anywhere in the code as well. I have run it before and after this code segment in the working version, and just before in the non-working version, and everything tests out okay. I have figured out several work-around for this, but I don't really like any of them, and they're not really good coding. More-so, I am just really confused about that is causing this problem. As I said, I can initialize and use this variable all I want, but after adding it all functions within the class suddenly perform errors, even if I try to make new ones. It is very odd. Plus there are strange things like how changing the size to 47 or below makes it work, but only the first iteration.Also, it seems to work with static variables.[Edited by - Chek on May 15, 2009 11:58:22 PM];Quote:I didn't use a vector or some other such container so that the memory was a set size, and that it saves speed by not being allocated dynamically.boost/tr1::array simply wraps a plain 'raw' array; it doesn't do any dynamic memory allocation. You would really be better off using array (for the reasons I mentioned earlier).Also, I think your logic regarding 'saving speed' is most likely flawed. Even if you were to substitute std::vector for the raw arrays you're using currently, it would most likely have zero impact on run-time performance (assuming release mode with range-checking turned off). If you used it exactly as you're using your arrays currently, the only dynamic allocation would be the initial sizing of the array, which, again, would have no measureable impact on the performance of your program (remember, this operation would only occur once, at the point where the vector object is created).Quote:The program keeps track of quite a few thigns at once, and sorting a dynamic array tends to hurt the overall performance.How is sorting a dynamic array slower than sorting a fixed-size array?Quote:sc is not null. It is not dynamically allocated. It is static, and defined at the beginning of the program loop.If it's not dynamically allocated, why are you passing it by pointer? (Passing by pointer isn't strictly necessary with dynamically allocated objects either, but it's fairly common to do so.)Quote:"arraySize" isn't in the actual program. It was jsut an example of the way it is set up. Instead each array has its own static const int variable, such as "max_pbullets" and "max_ebullets".What you've described suggests to me that it's not only possible that you're reading or writing past the end of an array somewhere, but probable. This is one of the reasons we use proper containers: so that we don't have to track array sizes manually.Again, I think a good first step would be to use a container class of some sort, and take advantage of whatever range-checking features it offers to catch out-of-bounds reads and writes. Also, by querying the container directly for its size, you'll catch errors such as iterating over an array using the wrong array size.I'd also recommend not worrying about 'saving speed' for the time being. A program that's fast but doesn't work correctly is more or less useless. Make it work, *then* make it fast. In this case, that means using whatever tools and techniques you can to make the coding and debugging process easier and more straightforward.   ;  The short answer is that you have a bug somewhere in your program, most likely a buffer overrun of some kind.If you don't already make use of asserts, now is the time to look into what they have to offer.   