I have a dynamic matrix in a class created by allocating memory in this way:
int **m; //this in the member head pointer
void allocate_mem(int ***ptr, unsigned r, unsigned c){
*ptr = new int *[r];
(*ptr)[0] = new int[r*c];
for(unsigned i = 1; i < r; i++)
(*ptr)[i] = (*ptr)[0] + i*c;
}
how can I call the pointers to the rows? I mean, m is the pointer to the array of pointers, *m is the pointer to the first row, but I don't know how to call the pointers to the other row
*m is the pointer to the row with index 0 indeed, but *m is equivalent to m[0]. So for other indexes use m[index]
Related
What's the meaning of the code below?
int **matrix = new int*[n]
What's the difference here between matrix and int*[n]?
It is an array of 'n' pointers, for which memory can be allocated and initialized in loop.
If n is 3, it is an array of 3 elements and each is pointer to int, can point to set of array of integer values like below.
matrix[0] -> Ox001 points to array of int [ 1 2 3 4]
matrix[1] -> Ox017 [ 5 6 7 8]
matrix[2] -> Ox024 [ 9 10 11 12]
Sample code like this
int **m = new int*[3];
for(auto i=0; i < 3; i++)
{
m[i] = new int[3];
for(auto j=0; j < 3; j++)
m[i][j] = 0;
}
for(auto i=0; i < 3; i++)
{
m[i] = new int[3];
for(auto j=0; j < 3; j++)
cout << m[i][j];
cout << "\n";
}
for instance there is cricket team and you need
Since you have Cricket* team;, this indicates you have one of two possible
situations:
1) a pointer to a single CricketPlayer (or any derived) type
2) a pointer to an array of CricketPlayer (but not derived) types.
What you want is a pointer to an array of CricketPlayer or derived types. So you
need the **.
You'll also need to allocate each team member individually and assign them to the array:
// 5 players on this team
CricketPlayer** team = new CricketPlayer*[5];
// first one is a bowler
team[0] = new Bowler();
// second one is a hitter
team[1] = new Hitter();
// etc
// then to deallocate memory
delete team[0];
delete team[1];
delete[] team;
In your query,
It can be understood as
int *matrix[]=new int*[n];
SO there are n pointers pointing to n places.
Because
int *foo;
foo=new int[5];
will also create 5 consecutive places but it is the same pointer.
In our case it is array of pointers
You need to notice some thing as follows:
int *p means that p is a pointer that points to an int variable or points to an array of int variables.
int* *p means that p is a pointer that points to an int* variable or points to an array of int* variables.
new int[5] is an array of 5 int variables.
new int*[5] is an array of 5 int* variables.
In this case, matrix is the second type so it can point to an array of int* variables so the statement:int **matrix = new int*[n] is legal
It means that you have declared a double pointer(of type int) called matrix and allocated an array of n int* pointers. Now you can use matrix[i] as an int* pointer (0 <= i < n). Later you might want to allocate memory to individual pointers as well like matrix[i] = new int[size];(size is an int or more appropriately size_t)
matrix is an object of type int **. This type is a pointer to pointer to int.
On the other hand, int * is a type, a pointer to int.
The expression:
new int*[n]
creates n adjacent objects of type int * somewhere in memory and returns a pointer to the first of them. In other words, it allocates and constructs n pointers to int; and returns a pointer to the first. Since the first (and each of them) are int *, the pointer pointing to the first is, in turn, of type int **.
It would be absolutely clear if you remember the operator associativity and precedence.
Going by that int *[n] will be interpreted by compiler : as array of " n pointer to integers".(as [ ] has greater precedence than *, so for easy understanding, compiler interprets it that way.).
Now comming to other side int ** matrix is pointer to pointer.
When you created an array of pointer,you basically have the address of the first location ,here first location stores an pointer to integer.
So,when you are storing the address of the first address of such array you will need pointer to a pointer to point the whole array.
//code for passing matrix as pointer and returning as a pointer
int ** update(int ** mat)
{
mat[0][1]=3;
return mat;
}
int main()
{ int k=4;
int **mat = new int*[k];
for(auto i=0; i < k; i++)
{
mat[i] = new int[k];
for(int j=0;j<k;j++)
{
if(i==j)
mat[i][j]=1;
else
mat[i][j]=0;
}
}
mat=update(mat);
for(auto i=0; i < k; i++)
{
for(auto j=0; j < k; j++)
cout << mat[i][j];
cout << "\n";
}
return 0;
}
This question already has answers here:
How do I declare a 2d array in C++ using new?
(29 answers)
Closed 4 years ago.
Dont know how to do this. Tried something like below.Want more optimisation in code.
Everyting should be in one function only,
guide me how to open close a file,
how to find character in each line,
increase the counter.
void simpleFileIn(void) {
string line;
ifstream myfile("example.txt");
if (myfile.is_open()) {
while (getline(myfile, line)) {
//found(line);
size_t size = strlen(line);
cout << line << '\n';
}
myfile.close();
}
else
cout << "Unable to open file";
}
the function simpleFileIn() should work, to open a file then close after work is done.
find out character a and count the integers.
want to close/ delete this question as i am in ban asking more help me. situation getting worse day after day
You need to allocate rows in a loop as you go:
int** pptr = new int* [rows]; // <<== rows, not cols
for(int i=0;i<rows;i++){
pptr[i] = new int[cols]; // <<== Add this line
for(int j=0;j<cols;j++){
cout<<"Enter value at "<<i<<j<<endl;
cin>>pptr[i][j];
cout<<"Value is "<<pptr[i][j]<<endl;
}
}
You also need to delete individual rows before deleting the array of pointers to them. Use delete[] operator with square brackets:
for(int i=0;i<rows;i++){
delete[] pptr[i];
}
delete[] pptr;
You do not need to assign NULLs to deleted pointers, unless you plan to reuse the pointer for something else later on.
You are allocing array of pointers wrong.
First you have to allocate enough space for row pointers
int** pptr = new int* [rows];
For every pointer enough space for col integers
for (int i = 0; i < cols; i++)
{
pptr[i] = new int [cols];
}
To delete arrays use delete[] instead of delete.
Delete every individual row
for (int i = 0; i < rows; i++)
{
delete [] pptr[i];
}
Then delte array of pointers
delete [] pptr;
There is no need to assigning NULL to deleted pointer since you wont use them again. Also in c++ you should use nullptr instead of NULL.
Here is the correct using of array of pointers.
Your mistakes
int* ptr = new int [rows];
int** pptr = new int* [cols];
*pptr=ptr;
Swapped rows & cols
Allocated memory only for first pointer/row, others were uninitialized -> UB
Used delete instead of delete[]
So there seems to be some confusion with allocation. From your code
int* ptr = new int [rows];
int** pptr = new int* [cols];
*pptr=ptr;
you have now created to 1-dimensional arrays. You then dereference the pptr and assign to it ptr this is the same as
pptr[0] = ptr;
So you are only initializing the very first column. You want to change this code to be
int** pptr = new int* [cols];
for (int i = 0; i < cols; ++i) {
pptr[i] = new int [rows];
}
This will allocate the memory properly
You can create a constructor of sorts for your 2D array so that you have one-line bookkeeping:
#include <iostream>
template <typename T>
T** new_( std::size_t rows, std::size_t columns )
{
auto dsize = rows * sizeof(T*);
auto rsize = columns * sizeof(T);
auto tsize = rows * rsize;
unsigned char* data = new unsigned char[ dsize + tsize ];
T** result = (T**)data;
T* table = (T*)(data + dsize);
while (rows--)
result[ rows ] = table + rows * columns;
return result;
}
int main()
{
int m; std::cout << "m? "; std::cin >> m;
int n; std::cout << "n? "; std::cin >> n;
// Create the new matrix
int** a = new_<int>( m, n );
// Do stuff with a[ r ][ c ] here.
// It looks and behaves JUST LIKE a normal 2D C array
// in all respects EXCEPT one: &a != &(a[0][0]).
// Use the latter when passing to a flat function!
// Delete it
delete [] a;
}
Enjoy the weirdness.
I'm currently using a particular API such that I must use raw pointers, however given the particular arrangement of the pointers I'm not sure how to best go about clearing the memory and avoiding any undefined behaviour in doing so.
double *data1 = new double[rows*columns];
double **data2 = new double*[rows];
data2[0] = data1; // Point to first row
for (int i = 1; i < columns; i++) {
data2[i] = data2[i - 1] + rows;
}
I've attempted something like below, but I don't think it's right.
for(int i = 0; i < rows; i++) {
delete [] data2[i];
}
delete [] data2;
delete [] data1;
Who owns What?
Is the question which will dictate how you delete objects.
What I think you're doing is creating one large array to hold a two-dimensional array of data, and then creating another array to hold pointers to the beginning of each row.
So that's two news and therefore two deletes.
It might be easier to visualise like this:
struct matrix_view
{
int rows, columns;
// this pointer owns a block of doubles
double* entire_buffer = nullptr;
// this pointer owns a block of pointers, but not the memory
// they point to
double** row_pointers = nullptr;
};
matrix_view create_matrix(int rows, int columns)
{
auto result = matrix_view{ rows, columns, nullptr, nullptr };
auto size = rows * columns;
result.entire_buffer = new double [size];
result.row_pointers = new double* [rows];
auto first = result.entire_buffer;
auto last = first + size;
auto dest = result.row_pointers;
while (first != last) {
*dest++ = first;
first += columns;
}
return result;
}
void destroy_matrix(matrix_view m)
{
// always destroy in reverse order
delete [] m.row_pointers;
delete [] m.entire_buffer;
}
When I make an array of integer pointers, I tried this.
int *arr = new int*[10];
This did not work but the following worked.
int **arr = new int*[10];
Why do we need double pointer?? And when I deference it, I had to do the following.
cout<<arr[0];
Why we do not need * in front of arr??
thanks!
new int*[10] allocates an array of ten pointers, and it yields a pointer to the first element of that array. The element type is itself a pointer, that's why you end up having a pointer to a pointer (to int), which is int**. And obviously int** isn't convertible to int*, so you have to declare arr with the appropriate type.
You are not just "making an array of integer pointers": you are dynamically allocating them.
Just like when you dynamically allocate an array of integers you get a single pointer through which to access them:
int* ptr = new int[5];
when you dynamically allocate an array of pointers-to-integer you get a single pointer through which to access those, too; since your element type is int*, adding the extra * gives you int**:
int** ptr = new int*[5];
As for dereferencing, I'm not quite sure what you're asking but that's just how the [] operator works; it adds n to a pointer then dereferences it:
int* ptr = new int[5];
*(ptr+1) = 42; // identical
ptr[1] = 42; // to this
If you forget dynamic allocation and just make a nice array, it's all much simpler:
int* array[5];
std::cout << array[0];
This statement is an expression for an 1D array of int
int* arr = new int [10]; // pointer to array of 10 int
This statement is an expression for a 2D array of int
int** arr = new int* [10]; // pointer to 10 pointers to arrays of 10 int
To populate the 1D array, you need to do this...
for (int i = 0; i < 10; i++) {
arr[i] = val; // where val can be any integer
}
To populate the 2D array, you need to do this...
int** arr2 = new int*[10];
for (int i = 0; i < 10; i++) {
arr2[i] = new int[10];
for (int j = 0; j < 10; j++) {
arr2[i][j] = val; // where val can be any integer
}
}
The * symbol between the variable type and the variable name is syntax for pointer. It changes type from int to pointer of int.
I have a triple pointer to an Object in C++ and I need to free the entire thing after use.
MyClass *** foobar = new MyClass **[10000];
How do I write the delete statement for this.
It depends on how you allocate the pointers-to-pointers. If you do:
int x;
int* p = &x;
int** pp = &p;
int*** ppp = &pp;
Then you don't have to delete anything.
On the other hand, if you do:
int* p = new int;
int** pp = &p;
int*** ppp = &pp;
Then you only have to delete p. For:
// i.e., allocate 1000 ints, return a pointer, and then get the address of that pointer
int** pp = &(new int[1000]);
// Oh, and get the address of the int**
int*** ppp = &pp;
You have to delete[] *pp (i.e., dereference pp to get the original pointer to the array of ints, and then delete[] the array).
How do you alloc it? Generally, if A is pointer to B, B is pointer to C and C is pointer to D (data), you need to free D, then C and B as the last one.
Anything you new[], you will have to delete[]. It's that simple.
If you do it at several levels, you will have to delete[] in the reverse order of the new[]'s.
If the only allocation that you have done is the one you show in the question, then you only need to do:
delete [] **foobar;
As that is the only memory that was actually acquired. If you have allocated memory to elements inside foobar, then you must clear them up in reverse order of creation.
Note that in most cases these types of structures can be simplified. For example, if the actual data to hold is a cube, you can allocate a single block of 1000*1000*1000 elements (that is a HUGE amount of them) and deallocate it with a single delete []. If you wrap the memory inside a class, then you can provide operator() that will map from three indices to the unique element in the sequential container. Take a look at the C++FAQ lite here.
3D memory allocation
int ***allocate3D(int ***mat, int k, int l, int m) {
mat = (int***) malloc( sizeof(int)*k*l*m );
for(int i=0;i<k;i++)
mat[i] = (int**) malloc ( sizeof(int)*l*m );
for(int i=0; i<k; i++) for(int j=0; j<l; j++)
mat[i][j] = (int*) malloc ( sizeof(int)*m );
return mat;
}
3D matrix deallocation:
void deAllocate3D(int ***mat, int k, int l, int m){
//Delete in reverse order of allocation
for(int i=0; i<k; i++) for(int j=0; j<l; j++) { free(mat[i][j]); mat[i][j] = NULL; }
for(int i=0; i<k; i++) { free(mat[i]); mat[i] = NULL; }
free(mat); mat = NULL;
}
Find the full source code here