mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	test: fix subtle bug in testplan.cpp
testplan.cpp had a subtle bug since converting from a fixed-size
cylinder table to a dynamic cylinder table.
As noted in equipment.h, pointers to cylinders are *not* stable
when the cylinder table grows. Therefore, a construct such as
        cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
        cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
        cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
can give dangling cyl0 and cyl1 pointers. This was not an issue
with the old table code, since it had a rather liberal allocation
pattern. However, when switching to std::vector<>, the problem
becomes active.
To "fix" this, simply access the highest index first. Of course,
this should never be done in real code! Therefore, add a
comment at each instance.
Quickly checked all other get_or_create_cylinder() calls and
they seemed to be safe.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
			
			
This commit is contained in:
		
							parent
							
								
									d27451979d
								
							
						
					
					
						commit
						9243921cbb
					
				
					 1 changed files with 40 additions and 10 deletions
				
			
		| 
						 | 
					@ -52,9 +52,12 @@ void setupPlan(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean36 = {{360}, {0}};
 | 
						struct gasmix ean36 = {{360}, {0}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 36000;
 | 
						cyl0->type.size.mliter = 36000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -83,9 +86,12 @@ void setupPlanVpmb45m30mTx(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 24000;
 | 
						cyl0->type.size.mliter = 24000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -114,9 +120,12 @@ void setupPlanVpmb60m10mTx(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix tx50_15 = {{500}, {150}};
 | 
						struct gasmix tx50_15 = {{500}, {150}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 24000;
 | 
						cyl0->type.size.mliter = 24000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -163,8 +172,11 @@ void setupPlanVpmb60m30minEan50(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix bottomgas = {{210}, {0}};
 | 
						struct gasmix bottomgas = {{210}, {0}};
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 36000;
 | 
						cyl0->type.size.mliter = 36000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -189,8 +201,11 @@ void setupPlanVpmb60m30minTx(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix bottomgas = {{180}, {450}};
 | 
						struct gasmix bottomgas = {{180}, {450}};
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 36000;
 | 
						cyl0->type.size.mliter = 36000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -239,9 +254,12 @@ void setupPlanVpmb100m60min(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 200000;
 | 
						cyl0->type.size.mliter = 200000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -269,9 +287,12 @@ void setupPlanVpmb100m10min(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 60000;
 | 
						cyl0->type.size.mliter = 60000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -321,10 +342,13 @@ void setupPlanVpmb100mTo70m30min(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean50 = {{500}, {0}};
 | 
						struct gasmix ean50 = {{500}, {0}};
 | 
				
			||||||
	struct gasmix oxygen = {{1000}, {0}};
 | 
						struct gasmix oxygen = {{1000}, {0}};
 | 
				
			||||||
	pressure_t po2 = {1600};
 | 
						pressure_t po2 = {1600};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl3 = get_or_create_cylinder(&dive, 3);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl3 = get_or_create_cylinder(&dive, 3);
 | 
					 | 
				
			||||||
	cyl0->gasmix = bottomgas;
 | 
						cyl0->gasmix = bottomgas;
 | 
				
			||||||
	cyl0->type.size.mliter = 36000;
 | 
						cyl0->type.size.mliter = 36000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -357,8 +381,11 @@ void setupPlanSeveralGases(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix ean36 = {{360}, {0}};
 | 
						struct gasmix ean36 = {{360}, {0}};
 | 
				
			||||||
	struct gasmix tx11_50 = {{110}, {500}};
 | 
						struct gasmix tx11_50 = {{110}, {500}};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cyl0->gasmix = ean36;
 | 
						cyl0->gasmix = ean36;
 | 
				
			||||||
	cyl0->type.size.mliter = 36000;
 | 
						cyl0->type.size.mliter = 36000;
 | 
				
			||||||
	cyl0->type.workingpressure.mbar = 232000;
 | 
						cyl0->type.workingpressure.mbar = 232000;
 | 
				
			||||||
| 
						 | 
					@ -386,9 +413,12 @@ void setupPlanCcr(struct diveplan *dp)
 | 
				
			||||||
	struct gasmix diluent = {{200}, {210}};
 | 
						struct gasmix diluent = {{200}, {210}};
 | 
				
			||||||
	struct gasmix ean53 = {{530}, {0}};
 | 
						struct gasmix ean53 = {{530}, {0}};
 | 
				
			||||||
	struct gasmix tx19_33 = {{190}, {330}};
 | 
						struct gasmix tx19_33 = {{190}, {330}};
 | 
				
			||||||
 | 
						// Note: we add the highest-index cylinder first, because
 | 
				
			||||||
 | 
						// pointers to cylinders are not stable when reallocating.
 | 
				
			||||||
 | 
						// For testing OK - don't do this in actual code!
 | 
				
			||||||
 | 
						cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
				
			||||||
	cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
						cylinder_t *cyl0 = get_or_create_cylinder(&dive, 0);
 | 
				
			||||||
	cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
						cylinder_t *cyl1 = get_or_create_cylinder(&dive, 1);
 | 
				
			||||||
	cylinder_t *cyl2 = get_or_create_cylinder(&dive, 2);
 | 
					 | 
				
			||||||
	cyl0->gasmix = diluent;
 | 
						cyl0->gasmix = diluent;
 | 
				
			||||||
	cyl0->depth = gas_mod(diluent, po2, &dive, M_OR_FT(3, 10));
 | 
						cyl0->depth = gas_mod(diluent, po2, &dive, M_OR_FT(3, 10));
 | 
				
			||||||
	cyl0->type.size.mliter = 3000;
 | 
						cyl0->type.size.mliter = 3000;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue