I am trying to make an array with a variable number of rows, but it will always have 4 columns. Is doing something like:
int** numGrades = new int* [num_exams];
for (int i = 0; i < num_exams; ++i)
{
numGrades[i] = new int[4];
}
a good way to do this? I feel like there's an easier way, but I can't think of one. Also, the array keeps giving me memory leaks so I'm wondering if that is because I'm doing something I shouldn't be. Vectors are banned for this program fyi.
You could make an array of rows.
struct Row{
int values[4];
};
Row* numGrades = new Row[num_exams];
You could skip the for loop:
int* numGrades = new int[num_exams*4];
int firstElement = numGrades[x];
int secondElement = numGrades[x+1];
int thirdElement = numGrades[x+2];
int fourthElement = numGrades[x+3];
By skipping the for loop you gain this:
You don't have to have a for-loop for freeing the memory:
delete[] numGrades;
The heap does not fragment so much because you don't call "new" so many times.
BUT it all depends what you are using it for. In modern C++ is not such a good idea to use dynamic but make a struct in a std::vector.
Maybe you can try this.
typedef int row[4];
//or
using row = int[4];
row *numGrades = new row[num_exams];
Allocating some number of arrays of fixed size is fine and advantageous in many cases.
In addition to a struct
(which is a very good option), another option is to declare a Pointer-To-Array of a fixed number of elements. The benefit there is you have a Single-Allocation and Single-Free for the block of memory. (as you do with an array of struct ) If you need to grow the block of memory (with a -- declare bigger block, copy existing to bigger, delete existing reallocation), it simplifies the process. In your case:
int (*numGrades)[4] = new int[num_exams][4];
Which will allocate num_exams
number of arrays of 4 int
all at once. That provides the benefit of a single delete[] numGrades;
when you are done with the memory.
A short example that uses a std::istringstream
to hold example values to be read into a block of memory containing fixes size arrays could be:
#include <iostream>
#include <sstream>
int main (void) {
std::istringstream iss { "1 2 3 4 5 6 7 8 9" };
int npoints = 3,
(*points)[3] = new int[npoints][3],
n = 0;
while (n < 3 && iss >> points[n][0] >> points[n][1] >> points[n][2])
n++;
for (int i = 0; i < n; i++)
std::cout << points[i][0] << " " << points[i][1] << " " << points[i][2] << '\n';
delete[] points;
}
( note: you should avoid using new
and delete
in favor of a container such as std::vector if this is for other than educational purposes)
Example Use/Output
$ ./bin/newptr2array3
1 2 3
4 5 6
7 8 9
Worth noting, the benefit of the struct
is that it will allow you to overload >>
and <<
with std::istream
and std::ostream
to provide a convenient functions to read and write the data you need.
So either way, a Pointer-to-Array of fixed elements, or creating a struct
and then an Array of struct
is perfectly fine.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.