Fundamental question- C++ learner
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11

Thread: Fundamental question- C++ learner

  1. #1
    Join Date
    Apr 2014
    Posts
    17

    Fundamental question- C++ learner

    Let us say I have dynamically allocated memory as below:


    double** pvalue = NULL; // Pointer initialized with null
    pvalue = new double [3][4]; // Allocate memory for a 3x4 array

    1) I now want to fill the double array with values. How is it possible do that?
    2) Secondly, if I want to query the size of the above double array at any point in the program, what is the ebst way to do that?

  2. #2
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,262

    Re: Fundamental question- C++ learner

    Code:
    double** pvalue = NULL; // Pointer initialized with null
    pvalue = new double [3][4]; // Allocate memory for a 3x4 array
    This is a c++11 way of allocating memory for multi-dimension arrays. As you are using MSVC 2008 this won't work for you.

    For further details and info about how to do it using c++98/03, see
    http://stackoverflow.com/questions/9...in-c-using-new
    http://www.cplusplus.com/forum/articles/7459/
    http://www.cplusplus.com/forum/general/49505/
    http://www.codeproject.com/Articles/...onal-arrays-in
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  3. #3
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,011

    Re: Fundamental question- C++ learner

    Quote Originally Posted by 2kaud View Post
    Code:
    double** pvalue = NULL; // Pointer initialized with null
    pvalue = new double [3][4]; // Allocate memory for a 3x4 array
    This is a c++11 way of allocating memory for multi-dimension arrays. As you are using MSVC 2008 this won't work for you.
    AFAIK, this is invalid in C++11 just as it is in C++03. The call to new returns a double*[4], which is not convertible to a double**.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  4. #4
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,262

    Re: Fundamental question- C++ learner

    Quote Originally Posted by D_Drmmr View Post
    AFAIK, this is invalid in C++11 just as it is in C++03. The call to new returns a double*[4], which is not convertible to a double**.
    See http://www.tutorialspoint.com/cplusp...mic_memory.htm where the code in the OP post #1 is shown.

    An 'easier' way in c++11 would be
    Code:
    auto pvalue = new double[3][4];
    which doesn't initialize the memory. Or
    Code:
    auto pvalue = new double[3][4]();
    which does initialize the memory.

    The array can then be used as
    Code:
    pvalue[0][0] = 2.1;
    pvalue[1][0] = 3.2;
    pvalue[0][1] = 4.6;
    pvalue[1][1] = 5.7;
    but for versions of c++ prior to c++11, you need to create a 2d array as an array of pointers to arrays - as in
    Code:
    int** pvalue = new double*[sizeX];
    for (int i = 0; i < sizeX; ++i)
        pvalue[i] = new double[sizeY];
    which is documented in the first link in my post #2.
    Last edited by 2kaud; April 23rd, 2014 at 03:29 AM. Reason: Changed as per post #5
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  5. #5
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,011

    Re: Fundamental question- C++ learner

    Quote Originally Posted by 2kaud View Post
    An 'easier' way in c++11 would be
    Code:
    auto pvalue = new double[3][4];
    which doesn't initialize the memory. Or
    Code:
    auto pvalue = new double[3][4]();
    which does initialize the memory.
    That's not the same. decltype(pvalue) will be double*[4], not double**.
    Quote Originally Posted by 2kaud View Post
    but for versions of c++ prior to c++11, you need to create a 2d array as an array of pointers to arrays - as in
    Code:
    int** pvalue = new double*[sizeX];
    for (int i = 0; i < sizeX; ++i)
        pvalue[i] = double int[sizeY];
    which is documented in the first link in my post #2.
    I assume you meant "new double[sizeY]" inside the loop. This is also considered bad style. You perform sizeX + 1 allocations, where only 2 are needed. Not to mention the use of new[] and raw pointers where std::vector can be used. The code can be simplified to
    Code:
    std::vector<double> valueData(sizeX * sizeY);
    std::vector<double*> values(sizeX);
    for (int x = 0; x < sizeX; ++x) {
        values[x] = &valueData[x * sizeY];
    }
    However, to avoid having to repeat this code in a lot of places, it's best to put it in a reusable matrix class.
    Also see Why shouldn't my Matrix class's interface look like an array-of-array?
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,011

    Re: Fundamental question- C++ learner

    Quote Originally Posted by atee View Post
    1) I now want to fill the double array with values. How is it possible do that?
    Assuming you use the code I posted above, you can access the data like this
    [code]
    int x = 1, y = 2; // second row, third column
    values[x][y] = 1.23;
    Quote Originally Posted by atee View Post
    2) Secondly, if I want to query the size of the above double array at any point in the program, what is the ebst way to do that?
    Code:
    const int nRows = int(values.size());
    const int nColumns = int(valueData.size());
    Note that I'm casting to int, because std::vector::size() returns a std::vector::size_type (which is typically an unsigned int). Using unsigned integers is a pain, because you cannot have negative numbers. This means that you should write
    Code:
    if (row + 1 < nRows)
    instead of
    Code:
    if (row < nRows - 1) // not safe when row and nRows are unsigned
    When using (signed) int, you don't have this problem so you are safe using the latter method.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,262

    Re: Fundamental question- C++ learner

    I assume you meant "new double[sizeY]" inside the loop.
    Yes. My bad. It was originally new int and I changed it to double int. Doh!!!!!

    Not to mention the use of new[] and raw pointers where std::vector can be used.
    Agreed, but the OP gave no hint of knowing about vectors.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  8. #8
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,262

    Re: Fundamental question- C++ learner

    The code can be simplified to
    Code:
    std::vector<double> valueData(sizeX * sizeY);
    std::vector<double*> values(sizeX);
    for (int x = 0; x < sizeX; ++x) {
        values[x] = &valueData[x * sizeY];
    }
    With some increase in the memory used.

    However, to avoid having to repeat this code in a lot of places, it's best to put it in a reusable matrix class.
    Also see Why shouldn't my Matrix class's interface look like an array-of-array?
    Agreed, but I think this is perhaps a little advanced for the OP.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  9. #9
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,011

    Re: Fundamental question- C++ learner

    Quote Originally Posted by 2kaud View Post
    With some increase in the memory used.
    When we are allocating POD types, probably. But the overhead is constant, i.e. independent of sizeX and sizeY.

    However, for non-POD types I think my solution will use less memory for non-tiny values of sizeX. Remember that operator new[] needs to store the number of elements allocated somewhere in order for operator delete[] to know how many elements to delete (i.e. how many times the destructor should be called, which is not necessary for a POD type). This means that your code from post #4 needs to store 2 * sizeX + 1 pointers in addition to the actual data to be stored (sizeX pointers that you allocated and one integer for each call to new[]). In contrast, the overhead of the two vectors in my code from post #5 is constant w.r.t. sizeX and sizeY.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  10. #10
    Join Date
    Dec 2012
    Location
    England
    Posts
    2,262

    Re: Fundamental question- C++ learner

    Remember that operator new[] needs to store the number of elements allocated somewhere in order for operator delete[] to know how many elements to delete
    Pity there's no mechanism to determine this number via code as that would answer the OP's question 2) re size query when vectors aren't used.
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  11. #11
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,760

    Re: Fundamental question- C++ learner

    new[] doesn't necessarily store the number of elements.
    how new[] and delete[] coordinate this is entirely compiler dependant.
    and some compiler do have a means to query this number, it's just not portable.



    and there is a portable mechanism to determine that number via code... you store the number of elements into a variable of your own :-)
    or... don't use new[] and delete[] but use a container class that does it for you.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center