-
April 21st, 2014, 07:45 AM
#1
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?
-
April 21st, 2014, 12:36 PM
#2
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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 22nd, 2014, 09:06 AM
#3
Re: Fundamental question- C++ learner
Originally Posted by 2kaud
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
-
April 22nd, 2014, 09:11 AM
#4
Re: Fundamental question- C++ learner
Originally Posted by D_Drmmr
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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 23rd, 2014, 01:48 AM
#5
Re: Fundamental question- C++ learner
Originally Posted by 2kaud
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**.
Originally Posted by 2kaud
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
-
April 23rd, 2014, 01:59 AM
#6
Re: Fundamental question- C++ learner
Originally Posted by atee
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;
Originally Posted by atee
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
-
April 23rd, 2014, 03:39 AM
#7
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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 23rd, 2014, 02:16 PM
#8
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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 23rd, 2014, 03:06 PM
#9
Re: Fundamental question- C++ learner
Originally Posted by 2kaud
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
-
April 23rd, 2014, 03:29 PM
#10
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. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 24th, 2014, 06:33 AM
#11
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|