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

Discussion in 'C++' started by howa, Dec 2, 2006.

  1. howa

    howa Guest

    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?
     
    howa, Dec 2, 2006
    #1
    1. Advertising

  2. howa wrote:
    > 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.

    --
    rbh
     
    Robert Bauck Hamar, Dec 2, 2006
    #2
    1. Advertising

  3. howa

    howa Guest

    Robert Bauck Hamar ¼g¹D¡G

    > howa wrote:
    > > 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.
    >
    > --
    > rbh


    thanks first...

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

    or it is possible?
     
    howa, Dec 2, 2006
    #3
  4. howa wrote:
    > Robert Bauck Hamar 寫é“:
    >
    >> howa wrote:
    >>> 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)

    --
    rbh
     
    Robert Bauck Hamar, Dec 2, 2006
    #4
  5. * howa:
    > Robert Bauck Hamar ??:
    >
    >> howa wrote:
    >>> 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.
    >>
    >> --
    >> rbh

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

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Dec 2, 2006
    #5
  6. howa

    Ivan Novick Guest

    > Alf P. Steinbach wrote:
    > #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
     
    Ivan Novick, Dec 3, 2006
    #6
  7. howa

    Salt_Peter Guest

    Ivan Novick wrote:
    > > Alf P. Steinbach wrote:
    > > #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


    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.
     
    Salt_Peter, Dec 3, 2006
    #7
  8. * Ivan Novick:
    >> Alf P. Steinbach wrote:
    >> #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?


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

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Dec 3, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ken
    Replies:
    24
    Views:
    3,876
    Ben Bacarisse
    Nov 30, 2006
  2. chris
    Replies:
    6
    Views:
    993
    chris
    Oct 28, 2005
  3. linq936
    Replies:
    21
    Views:
    698
    Pete Becker
    Sep 19, 2007
  4. Josh Sharpe
    Replies:
    1
    Views:
    212
    Brian Candler
    Sep 21, 2010
  5. py
    Replies:
    9
    Views:
    433
Loading...

Share This Page