comparison liboctave/dim-vector.h @ 9840:c0b54271904b

improve safe numel() calculation for arrays
author Jaroslav Hajek <highegg@gmail.com>
date Thu, 19 Nov 2009 15:48:33 +0100
parents 26abff55f6fe
children cddd5c3d5f04
comparison
equal deleted inserted replaced
9839:3e8b4c80ae63 9840:c0b54271904b
23 23
24 #if !defined (octave_dim_vector_h) 24 #if !defined (octave_dim_vector_h)
25 #define octave_dim_vector_h 1 25 #define octave_dim_vector_h 1
26 26
27 #include <cassert> 27 #include <cassert>
28 #include <limits>
28 29
29 #include <sstream> 30 #include <sstream>
30 #include <string> 31 #include <string>
31 32
32 #include "lo-error.h" 33 #include "lo-error.h"
325 retval *= elem (i); 326 retval *= elem (i);
326 327
327 return retval; 328 return retval;
328 } 329 }
329 330
331 // The following function will throw a std::bad_alloc ()
332 // exception if the requested size is larger than can be indexed by
333 // octave_idx_type. This may be smaller than the actual amount of
334 // memory that can be safely allocated on a system. However, if we
335 // don't fail here, we can end up with a mysterious crash inside a
336 // function that is iterating over an array using octave_idx_type
337 // indices.
338
339 octave_idx_type safe_numel (void) const
340 {
341 octave_idx_type idx_max = std::numeric_limits<octave_idx_type>::max () - 1;
342 octave_idx_type n = 1;
343 int n_dims = length ();
344 for (int i = 0; i < n_dims; i++)
345 {
346 n *= rep[i];
347 if (rep[i] != 0)
348 idx_max /= rep[i];
349 if (idx_max <= 0)
350 throw std::bad_alloc ();
351 }
352 return n;
353 }
354
330 bool any_neg (void) const 355 bool any_neg (void) const
331 { 356 {
332 int n_dims = length (), i; 357 int n_dims = length (), i;
333 for (i = 0; i < n_dims; i++) 358 for (i = 0; i < n_dims; i++)
334 if (elem (i) < 0) break; 359 if (elem (i) < 0) break;