Is it safe to assume default value from dynamic memory allocation?

H

howa

e.g.

#include<iostream>

using namespace std;

int main() {

double *d = new double[100];

d[1] = d[0] + 1;
cout<<d[1]<<endl;
}

since i don't get any warning...so

is it safe to assume d[0..99] will be initialized to 0 at the begining?
 
R

Robert Bauck Hamar

howa said:
e.g.

#include<iostream>

using namespace std;

int main() {

double *d = new double[100];

d[1] = d[0] + 1;
cout<<d[1]<<endl;
}

since i don't get any warning...so

is it safe to assume d[0..99] will be initialized to 0 at the begining?

No.
 
H

howa

Robert Bauck Hamar ¼g¹D¡G
howa said:
e.g.

#include<iostream>

using namespace std;

int main() {

double *d = new double[100];

d[1] = d[0] + 1;
cout<<d[1]<<endl;
}

since i don't get any warning...so

is it safe to assume d[0..99] will be initialized to 0 at the begining?

No.

thanks first...

so how to give them a default value without using a loop?

or it is possible?
 
R

Robert Bauck Hamar

howa said:
Robert Bauck Hamar 寫é“:
howa said:
e.g.

#include<iostream>

using namespace std;

int main() {

double *d = new double[100];

d[1] = d[0] + 1;
cout<<d[1]<<endl;
}

since i don't get any warning...so

is it safe to assume d[0..99] will be initialized to 0 at the begining?
No.

thanks first...

so how to give them a default value without using a loop?

or it is possible?

First of all. Had you used a class with a default constructor, all
elements had been initialized.

Preferably, use a vector:

#include <vector>
#include <iostream>
#include <ostream> //required for endl!

int main() {
using namespace std;
vector<double> d(100, 0.0);
d[1] = d[0] + 1;
cout << d[1] << endl;
//no need to delete [] d, as you forgot.
}

If you must use an array, you can fill it easily:
#include <algorithm>
....
fill(d, d+sizeof d/sizeof d[0], 0.0)
 
A

Alf P. Steinbach

* howa:
Robert Bauck Hamar ??:
howa said:
e.g.

#include<iostream>

using namespace std;

int main() {

double *d = new double[100];

d[1] = d[0] + 1;
cout<<d[1]<<endl;
}

since i don't get any warning...so

is it safe to assume d[0..99] will be initialized to 0 at the begining?
No.

thanks first...

so how to give them a default value without using a loop?

or it is possible?

#include <iostream> // std::cout
#include <ostream> // operator<<, std::endl
#include <vector> // std::vector

int main()
{
using namespace std;
vector<double> d( 100 );

d.at( 1 ) = d.at( 0 ) + 1;
cout << d.at( 1 ) << endl;
}

Note everything in this program. ;-)
 
I

Ivan Novick

Alf said:
#include <iostream> // std::cout
#include <ostream> // operator<<, std::endl
#include <vector> // std::vector

int main()
{
using namespace std;
vector<double> d( 100 );

d.at( 1 ) = d.at( 0 ) + 1;
cout << d.at( 1 ) << endl;
}

Note everything in this program. ;-)
I'll bite. Can you please explain what you have done with this code?
Especially the 3rd line in main?

Thanks,
Ivan
-
http://www.0x4849.net
 
S

Salt_Peter

Ivan said:
I'll bite. Can you please explain what you have done with this code?
Especially the 3rd line in main?

Thanks,
Ivan

You can specify an alternate value for the elements when constructing
the std::vector.
The at() member function is a range-checking accessor to the elements
stored in that vector.
Its simply an alternate to op[ ] since op[ ] does no such range check.

In the case you have an unquencheable desire to throw at()'s exception,
capture it in a catch block:

#include <iostream>
#include <ostream>
#include <vector>
#include <iterator> // for std::eek:stream_iterator
#include <stdexcept> // for std::exceptions

int main()
{
std::vector< double > vd(10, 1.1); // 10 doubles, all set to 1.1

// iterate through and stream to cout
// each of the vector's elements
std::copy( vd.begin(),
vd.end(),
std::eek:stream_iterator< double >(std::cout, "\n") );

try {
// there is *no* tenth element
std::cout << vd.at(10) << std::endl;
}
catch( const std::exception& r_e )
{
std::cerr << "Error:";
std::cerr << r_e.what();
std::cerr << std::endl;
}
}

Personally, the try-catch block is a requirement when developing code.
 
A

Alf P. Steinbach

* Ivan Novick:
I'll bite. Can you please explain what you have done with this code?
Especially the 3rd line in main?

Ah, yes. It wasn't meant as a mystery. The third line could have been
written as just

d[1] = d[0] + 1;

But in general, operator[] does no bounds checking, so if the indices
are out of bounds (i.e. negative or larger than the vector size) the
result is immediate C++ Undefined Behavior, which is difficult to detect
and debug because anything or nothing might happen.

'at' does bounds checking and throws an exception for out-of-bounds, and
is otherwise the same as operator[]; therefore recommended as default,
writing

d.at(1) = d.at(0) + 1;

unless profiling shows this to be a real bottlneck performancewise,
/and/ a reasonable proof that no out-of-bounds access happens, exists.

The immediate (possible) Undefined Behavior of operator[] is with 'at'
turned into a more well-behaved exception, which is more easily
detectable and easy to debug.

Since this program has no try-catch the formal C++ Undefined Behavior
again rears it ugly head (or would that be "behind"?) at a higher level
-- when the possible exception propagates out of 'main'.

Happily, on most C++ implementations an exception out of 'main' causes
well-defined /implementation defined/ behavior, which we usually call a
"crash"; again, easy to detect and debug. In practice it can be much
easier to detect and debug than if there is a try-catch in 'main'. On
the other hand, for a program distributed to end-users, the end-user
will not necessarily have a debugger or understand a core dump or
whatever a "crash" is on the end-user's machine, so for such a program
it should perhaps be written as

#include <cstddef> // EXIT_SUCCESS, EXIT_FAILURE
#include <stdexcept> // std::exception
...

int main()
{
using namespace std;
try
{
// Former contents of 'main', then
return EXIT_SUCCESS;
}
catch( std::exception const& x )
{
cerr << "!Sorry, I crashed (program failure)." << endl;
cerr << "!Technical info: " << x.what() << endl;
return EXIT_FAILURE;
}
}

And of course that construction can be written once and for all and
reused, just calling a 'cppMain' function (or whatever) from 'main'.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top