Thread: Problem with new. Please help.

  1. #1
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216

    Problem with new. Please help.

    I compiled the following code using 3 different compiler. Each gave me different result.

    Code:
    #include <iostream>
    #include <cstddef>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main(void)
    {
        int *a = new int [10] ();
        for ( size_t i = 0; i < 10; i++ ) {
            cout << a[i] << ' ';
        }
        cout << endl;
    
        cin.get();
        return 0;
    }
    When using MSVC++6, the program displays:
    -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451
    When using Dev-C++4, the program displays:
    2557144 2557144 0 0 0 0 0 0 0 0
    And when using g++3.2, the program displays:
    0 0 0 0 0 0 0 0 0 0
    which is what I'm expecting.

    The following quoted sentences are from C++ Primer, 4th Edition
    we can value-initialize the elements by following the array size by an empty pair of parentheses:

    int *pia2 = new int[10] ();

    The parentheses are effectively a request to the compiler to value-initialize the array, which in this case sets its elements to 0.
    Does these sentences mean that it's in standard that each element in the dynamically allocated array should be initialized to 0?
    Is it because msvc++6 and dev-c++ are too old to support this newly standard? Or whether the elements are initialized to 0 or not is implementation-dependent?
    Last edited by Antigloss; 06-17-2005 at 05:04 AM.

  2. #2
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    This time, I removed the '()', but the result remains the same as I mentioned before.
    Code:
    #include <iostream>
    #include <cstddef>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main(void)
    {
        int *a = new int [10];  // removed '()'
        for ( size_t i = 0; i < 10; i++ ) {
            cout << a[i] << ' ';
        }
        cout << endl;
    
        cin.get();
        return 0;
    }
    When using MSVC++6, the program displays:

    -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451
    When using Dev-C++4, the program displays:
    2557144 2557144 0 0 0 0 0 0 0 0
    And when using g++3.2, the program displays:
    0 0 0 0 0 0 0 0 0 0
    Last edited by Antigloss; 06-17-2005 at 05:13 AM.

  3. #3
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Remember one thing - dynamic variables are never initialized by the compiler. Therefore it is good practice to first assign them a value, or your calculations may not come out right. There are two ways of doing this :

    dp = new double;
    *dp = a;

    or

    dp = new double(a);

    where a is the initial value. I personally recommend the second version as it is more suggestive and also more compact.
    ...
    ...
    Arrays allocated in the heap are similar to those allocated in the data or stack segments, so we may access an arbitrary element using the indexing operator []. For example the next loop initializes each element of the array to zero :

    for (int i = 0; i < 100; ++i)
    table[i] = 0;

    Bad news is C++ does not provide any method of initializing heap arrays as you would an ordinary dynamic variable, so we have to do it ourselves using a loop similar to the one above. The following line will generate errors at compilation :

    table = new int[100](0);
    http://www.codersource.net/c++_dynam...llocation.aspx

  4. #4
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    From C++ Primer, Fourth Edition By Stanley B. Lippman, Josée Lajoie, Barbara E. Moo

    4.3. C-Style Character Strings

    ... ...
    ... ...

    Dynamic Arrays of const Objects

    If we create an array of const objects of built-in type on the free store, we must initialize that array: The elements are const, there is no way to assign values to the elements. The only way to initialize the elements is to value-initialize the array:

    // error: uninitialized const array
    const int *pci_bad = new const int[100];
    // ok: value-initialized const array
    const int *pci_ok = new const int[100]();



    It is possible to have a const array of elements of a class type that provides a default constructor:

    // ok: array of 100 empty strings
    const string *pcs = new const string[100];



    In this case, the default constructor is used to initialize the elements of the array.

    Of course, once the elements are created, they may not be changedwhich means that such arrays usually are not very useful.
    Code:
              // ok: value-initialized const array
              const int *pci_ok = new const int[100]();
    These code fails in msvc++6 and dev-c++4, but successes in g++3.2. And in g++3.2, the elements of the array are initialized to 0. I guess in newly standard, the dynamically allocated array is initialized when adding '()' following the bracket pair.

  5. #5
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Antigloss
    These code fails in msvc++6 and dev-c++4, but successes in g++3.2. And in g++3.2, the elements of the array are initialized to 0. I guess in newly standard, the dynamically allocated array is initialized when adding '()' following the bracket pair.
    So, you just have some extra code, like a loop or something to initialize your array after you've allocated it. One way to do this is to use the fill function.

    Code:
    #include <algorithm>
    
    ...
    
    int * iptr = new int[10];           // Allocate space for 10 ints
    
    if(iptr) std::fill(iptr,iptr+10,0); // Set our 10 ints to 0
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  6. #6
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Quote Originally Posted by hk_mp5kpdw
    So, you just have some extra code, like a loop or something to initialize your array after you've allocated it.
    No. I have not add a loop or anything else to initialize the array.
    And note that this code allocates dynamic arrays of const objects:
    Code:
    const int *pci_ok = new const int[100]();
    Here is my code. g++3.2 compiles it successfully. But in msvc++6 and dev-c++4, this code cannot be compiled.
    Code:
    #include <iostream>
    #include <cstddef>
    
    using std::cout;
    using std::endl;
    using std::cin;
    
    int main(void)
    {
    	const int *pci_ok = new const int[10](); // note that here add '()' after the bracket pair
    	for ( size_t i = 0; i < 10; i++ ) {
    		cout << pci_ok[i] << ' ';
    	}
    	cout << endl;
    
        cin.get();
        return 0;
    }

  7. #7
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Antigloss
    No. I have not add a loop or anything else to initialize the array.
    I was not saying you had extra code... I was suggesting adding code to do the initialization/setting to 0. But yes, I did not see the 'const' part of the problem you had.

    Might be reaching here, but this works on msvc to set the memory of a pointer to const int to all 0's:
    Code:
    const int * a = new int[10];
    int * b = const_cast<int*>(a);
    fill(b,b+10,0);
    for ( size_t i = 0; i < 10; i++ )
    {
        cout << a[i] << ' ';
    }
    cout << endl;
    Should output: 0 0 0 0 0 0 0 0 0 0
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  8. #8
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    You misunderstood me. Maybe that's because of my poor English. I'll try my best to express myself.

    The following quoted sentences are from C++ Primer, 4th Edition
    we can value-initialize the elements by following the array size by an empty pair of parentheses:

    int *pia2 = new int[10] ();

    The parentheses are effectively a request to the compiler to value-initialize the array, which in this case sets its elements to 0.
    Does the quoted sentences mean that it's in C++ Standard that each element in the dynamically allocated array should be initialized to 0 when we write int *pia2 = new int[10] (); ?

    In g++, the elements are initialized to 0, but not in msvc++6 or dev-c++4.

    My question is: int *pia2 = new int[10] (); is in C++ Standard to initialize the elements to 0 or is implementation-dependent?

  9. #9
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    I guess it's a newly standard that we can write int *pia2 = new int[10] (); to initialize the elements to 0, because in C++ Primer, 4th Edtion, the author say that we can define Dynamic Arrays of const Objects.

    From C++ Primer
    If we create an array of const objects of built-in type on the free store, we must initialize that array: The elements are const, there is no way to assign values to the elements. The only way to initialize the elements is to value-initialize the array:

    // error: uninitialized const array
    const int *pci_bad = new const int[100];
    // ok: value-initialized const array
    const int *pci_ok = new const int[100]();

    Of course, once the elements are created, they may not be changed which means that such arrays usually are not very useful.

  10. #10
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Because const object must be initialized when it is defined. So if it's possible to define Dynamic Arrays of const Objects, then the dynamic array of const objects must be initialized when it is defined. That's to say there is a way to initialize dynamic array. C++ Primer says that we can use int *pia2 = new int[10]() to initialize each element of the dynamic array to 0. This code will work in g++3.2 and initialize the elements to 0. But in msvc++6 and dev-c++4, the elements are left uninitialized. Is it because msvc++6 and dev-c++4 are too old so that they don't support this newly standard? Or is it because int *pia2 = new int[10]() is never a c++ standard to initialize the elements to 0.

  11. #11
    C/C++Newbie Antigloss's Avatar
    Join Date
    May 2005
    Posts
    216
    Sorry about my poor English. Could anyone understand my question now?

  12. #12
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    I understand what you're saying, I just don't have a copy of the standard to look at so I don't know what it says about this. I know MSVC++6 is not fully compliant with the standard so it could quite easily be an issue with MSVC that is causing your headaches.

    But... my previous post showed how you could get around the issue by initializing the array after it was allocated even though it was supposed to be const. Saying "The only way to initialize the elements is to value-initialize the array" is not quite accurate. There are almost always exceptions to the rules.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    http://www.boost.org/libs/utility/value_init.htm

    Value-initialization was not originally part of the C++ standard, but only of the first technical corrigendum, 2001. Which is why VC++6 (1996/7 I think) and Dev-C++4 (isn't that a GCC 2.95?) don't support it.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    This code will work in g++3.2 and initialize the elements to 0. But in msvc++6 and dev-c++4, the elements are left uninitialized. Is it because msvc++6 and dev-c++4 are too old so that they don't support this newly standard? Or is it because int *pia2 = new int[10]() is never a c++ standard to initialize the elements to 0.
    If you are going to have lots of these types of questions, then you can buy a copy of the C++ standard and look it up. There are several people on this forum that have copies and can look it up for you. In the future, if you have a standards question, put that in the topic of the post:

    Question about C++ standard?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM