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;
}
Related
My problem is when I declare an array int** arr =new* int[n] and I want to assign to it pointer to array and later change that pointer to a different pointer which is copy of it values + one other number ,it brakes down and appears (probably) infinite loop . Can you say how to do this in proper way using some low tools with c++/c or can you correct my code?
Additional explenation: the code is producing very simple output but it is not important. I want to create program to change in array pointer(int*arr) in specific index pointer to diffrent pointer . But additionally pointers direct first element in arrays .Also diffrennce beetween new and old array (which is changed in int**arr in index for example 0) is that new is bigger on a new element (int this case new number).So this output is only checking if it works.
Below is my whole code
#include <iostream>
using namespace std;
void stepwise_fill_array(int ** arr, int N, int index)
{
for(int j=1;j<=10;j++)
{
int* poi=arr[index];//getting pointer to array which i wannna change
int size=0;
while(poi){poi++;size++;}//getting size of pointer array from arr
int* n= new int[size+1];//declaring the new array
for(int i=0; i<size;i++)//copying from all values from old array to new one
n[i]=poi[i];
delete[] poi;
n[size]=j;//adding to the end new value
arr[index]=n;//asigning arr[0] to new diffrent array
}
for(int i=0;i<10;i++)
cout<<arr[0][i]<<" ";
//should print 1 2 3 4 5 6 7 8 9 10
}
int main(){
int N = 10; // how big array should be and how many times it should expand
int** arr = new int*[N];//declaring our array to pointer
for(int i=0;i<N;i++)
{
arr[i]=nullptr;
}
int index =0;//index where I would change the pointer of arr
stepwise_fill_array(arr,N,index);
}
In advance thanks for your help :)
Your style of coding and explaining of problem is tragic , but fortunately I copied with it. When you are trying to get size from while(poi){poi++;size++;} you are getting in trouble. In C\C++ is no possibility to check size of array from pointer to this array. Instead you need increment size in every iteration of function stepwise_fill_array.
Below I give you correct solution(in code are leaks but I doesn't affect in much way on efficiency):
void stepwise_fill_array(int **arr, int N, int index)
{
int size = 0;
for (int j = 1; j <= 10; j++)
{
int *poi = arr[index]; //getting pointer to array which i wannna change
int *n = new int[size + 1]; //declaring the new array
for (int i = 0; i < size; i++)
{
n[i] = poi[i]; //copying from all values from old array to new one
}
n[size] = j; //adding to the end new value
arr[index] = n; //asigning arr[0] to new diffrent array
size++;
}
for (int i = 0; i < 10; i++)
cout << arr[0][i] << " ";
//should print 1 2 3 4 5 6 7 8 9 10
}
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.
So the lecture example has the following code
int **a;
a = new int*[10];
for (int i = 0; i < 10; ++i){
a[i] = new int[5];
for (int j = 0; j < 5; ++j){
a[i][j] = i*10+5;
}
}
And I have a few questions about the above code (and multidimensional arrays on the heap in general):
Do we have to initialize every element in the array as shown? Or is it suffice to cut the code after the a[i] = new int [5]?
I know with arrays allocated on the stack, it is illegal to use a variable as the stack size as
cin >> n;
int a[n];
but is it legal for heap-allocated arrays? As in, a = new int[n]?
Why is it a double pointer pointing to this array? Usually for 1D arrays, we used a single pointer as int *a = new int[10]? If I wanted the value of the array element itself, do I deference twice as **a? Or do I still do *a?
So say I have a 2D array of objects of some Class. How would I access the member field var of the ith, jth element? What if I want to invoke the member function of the object in the ith, jth element?
You don't have to initialize every element in the array. If you don't, the contents of the array will be undefined. Alternatively, you can zero-initialize with new int[5]().
a = new int[n] works on the heap because there's actually a run-time call to mark new memory for use as the data a is pointing to. It can't work on the stack because the compiler needs to know how big the stack frame is for any particular function call, so the value must be computable at compile time.
You need a double pointer because a is a pointer to a pointer to an integer. It points to an array of arrays, each of which needs to be dereferenced when accessing the value. You would typically use a[i][j] to access a specific element, which effectively double-deferences.
If the number of columns in the matrix is known at compile time, you can just allocate a matrix:
int nrow = 10; // number of rows assigned at run time
int (*a)[5]; // pointer to array of 5 ints
a = new int[nrow][5]; // allocate matrix
for (int i = 0; i < nrow; ++i) // initialize matrix
for (int j = 0; j < 5; ++j)
a[i][j] = i*nrow+j;
// ...
delete[] a;
I am trying to code a class that represents a set of integers. It's a homework assignment but for the life of me I cannot figure out this issue.
In the class "IntSet", I have two private variables; one is a pointer to an array the other is the size of the array. I can create objects of this class and they work as intended. But I have this function named "join" that returns an object of the IntSet class. It essentially concatenates the arrays together then uses that array to create the returning object.
Here is my code:
#include <iostream>
using namespace std;
class IntSet {
int * arrPtr;
int arrSize;
public:
//Default Constructor
IntSet() {
int arr[0];
arrPtr = arr;
arrSize = 0;
}
//Overloaded Constructor
IntSet(int arr[], int size) {
arrPtr = arr;
arrSize = size;
}
//Copy Constructor
IntSet(const IntSet &i) {
arrPtr = i.arrPtr;
arrSize = i.arrSize;
}
/*
* Returns a pointer to the first
* element in the array
*/
int* getArr() {
return arrPtr;
}
int getSize() {
return arrSize;
}
IntSet join(IntSet &setAdd) {
//Make a new array
int temp[arrSize + setAdd.getSize()];
//Add the the values from the current instance's array pointer
//to the beginning of the temp array
for (int i = 0; i < arrSize; i++) {
temp[i] = *(arrPtr + i);
}
//Add the values from the passed in object's array pointer
//to the temp array but after the previously added values
for (int i = 0; i < setAdd.getSize(); i++) {
temp[i + arrSize] = *(setAdd.getArr() + i);
}
//Create a new instance that takes the temp array pointer and the
//size of the temp array
IntSet i(temp, arrSize + setAdd.getSize());
//Showing that the instance before it passes works as expected
cout << "In join function:" << endl;
for (int j = 0; j < i.getSize(); j++) {
cout << *(i.getArr() + j) << endl;
}
//Return the object
return i;
}
};
int main() {
//Make two arrays
int arr1[2] = {2 ,4};
int arr2[3] = {5, 2, 7};
//Make two objects normally
IntSet i(arr1, 2);
IntSet j(arr2, 3);
//This object has an "array" that has arr1 and arr2 concatenated, essentially
//I use the copy constructor here but the issue still occurs if I instead use
//Inset k = i.join(j);
IntSet k(i.join(j));
//Shows the error. It is not the same values as it was before it was returned
cout << "In main function:" << endl;
for (int l = 0; l < k.getSize(); l++) {
cout << *(k.getArr() + l) << endl;
}
return 0;
}
The program compiles and the output as of now is:
In join function:
2
4
5
2
7
In main function:
10
0
-2020743083
32737
-2017308032
I don't know why but the 10 and 0 are always the same every time I recompile and run. Also, if I print out the address of the pointer rather than the value(in both the join function and the main function), I get the same memory address.
Sorry if I misuse terms, I come from a java background, so pointers and such are a little new to me. If any clarification is needed, please ask.
Thanks in advance.
int temp[arrSize + setAdd.getSize()];
This is a local array, its lifetime ends once the function returned.
IntSet i(temp, arrSize + setAdd.getSize());
Here you are constructing an IntSet with this array. In fact the constructor simply changes a member pointer to the value of temp:
IntSet(int arr[], int size) {
arrPtr = arr;
arrSize = size;
}
As a result, since the lifetime of the object that temp and consequently also i.arrPtr is pointing to ends after leaving join, you will have a wild pointer. Dereferencing this pointer later in main invokes undefined behavior.
You need to allocate the array dynamically with new[] and delete it later with delete[]. The same goes for your constructors. Also note that if you use new[] in join and delete[] in the destructor, then you also have to make sure that the copy constructor actually copies the array (create new array with new[] and copy contents). If you simply assign the pointer then both the source and destination object will point to the same array and they will also both try to delete it at deconstruction, again invoking undefined behaviour.
But since this C++, you might as well use a std::vector which does all of this for you. (or std::set if you actually want a integer set)
The quickest fix with your code is to change
int temp[arrSize + setAdd.getSize()];
into this
int * temp = new int[arrSize + setAdd.getSize()];
The thing is that you allocated temp on the stack, so when join() returns that memory is releases. By allocating memory on the heap (as per the fix) the memory is not released when join() returns.
There are other things wrong with your code -- depending on the point of the assignment. I think most of these will be fixed when you consider the implications of having memory on the heap.
I'd like to test a function that takes runtime-allocated multidimensional arrays, by passing it a hardcoded array.
The function has a signature of void generate_all_paths(int** maze, int size) and the array is defined as int arr[5][5] = {REMOVED}.
I'm not exactly sure how to properly coerce the array for the function (or if that is impossible).
This multi dimensional array topic unfortunately confuses so many C++ programmers. Well, here is the solution:
void generate_all_paths(int (*maze)[5], int size);
That is what the function declaration has to look like. An alternative, but fully equivalent is
void generate_all_paths(int maze[][5], int size);
Both are creating a parameter that is a pointer to an array of 5 integers. You can then pass your array of arrays of 5 integers to that function:
generate_all_paths(arr, 5);
Because your array's first element is an array of 5 integers, it will be converted automatically (implicitly) to a pointer to that first element when passed to that function.
In the comments, you have shown you are bound to an int**, because both your inner and outer dimension must have runtime values. A multi-dimensional array can not be used anymore. What you can do for testing purposes then is to create an array of pointers like this:
int store[5 * 5] = { ..... };
int *arr[5] = { store, store + 5, store + 10, store + 15, store + 20 };
Then, actually, you can have your function accept a int**. As the first element of you array then is a int*, it will be converted to a int** automatically. Another way of doing this is keeping the data in the 2 dimensional array, but just creating a "view" structured of pointers to that array:
int *arr[5] = { store[0], store[1], store[2], store[3], store[4] };
Where store is your int[5][5] array. Since store[n] accesses the n'th sub-array of that two-dimensional array and the element type of it is int, the pointer-converted type of it is int*, which will be compatible again.
You can write:
void display(char **a)
And then use a[i][j] to refer to elements in it.
The declaration char ** means "pointer to pointer to integer". To break it down into steps:
char *b = a[i];
That gets you a pointer to the first element of the i'th array in the array-of-arrays.
char c = b[j];
That gets you the j'th element in the array b.
The next problem you'll have is of allocating such an array-of-arrays.
char **arrayOfArrays = new char *[10];
for (int n = 0; n < 10; n++)
arrayOfArrays[n] = new char[20];
That allocates an array of 10 arrays, each "child" array having 20 characters.
In C/C++, array access syntax is just a way of retrieving a value some distance away from a pointer.
char *p = "Hello";
char *pl = p + 2; // get pointer to middle 'l'
char l = *pl; // fetch
char o = p[4]; // use array syntax instead
void display(char ** array)
should work. Also I don't think that it is a reserved word in standard C/C++.
And also, why is array a reserved word?
It isn't. You are probably using Visual Studio where it's displayed as a keyword due to its use in C++/CLI as a native managed type. However, this is irrelevant for C++ and Visual Studio is misleading in that regard.
As to your problem: You can simply pass a pointer-to-pointers-to-char and then pass your nested array directly (provided you are working with a dynamically allocated array):
void display(char** array) …
That said, your function assumes a fixed, known array length and some other details. Better would be to use a nested std::vector, or std::string (for instance). Using such existing data types makes your life much easier.
void display(std::vector<std::string> const& array) {
for (size_t i = 0; i < array.length(); ++i)
cout << array[i] << endl;
}
To take advantage of this, your calling code needs to be changed as well to use these data structures instead of plain C arrays on chars.
The Earwicker's answer is missing an important fact. What he is proposing is an array of arrays. For the first this wastes memory for the array of pointers ("char **arrayOfArrays = new char *[10]" is the creation point of this). For the second the array of chars may then not be a continuous block of memory, which is often a problem.
The only workaround in C++ is to create a one dimensional array and calculate the indexes when you need them.
char *b = new char[width*height];
then you can refer to element x,y (x is along width, y along height) like this
char c=b[width*y+x];
This may be however a bit slower than the solution above (measured on GCC 3.4.5), so if you are not interested in continuous memory (for example you always access the elements with [][], never by adding integer to a pointer and dereferencing it), then you should use the array af arrays. However, if you are interested in having the continuous memory, e.g. to pass it as initializer to an std::string object or to send it as a whole through a network, you should use the second one.
The best is to use pointers, but Borland C++ admits passing arrays as parameters for functions. Look at this code (includes: iostream and conio):
////////////////////////////////////////////
void ReceivedArray(char x[5]){
for (int i=0; i<5; i++ )
cout << x[i];
}
void main(){
char *x = new char[5];
for (int i=0; i<5; i++ )
x[i]='o';
ReceivedArray(x);
getchar();
}
///////////////////////////////////////////////////////////////
For passing 2D arrays (oops! some lines in spanish, sorry!):
(includes: iostream, stdlb, stdio and math)
/////////////////////////////////////////////////
using namespace std;
void ver(int x[][20]){
for(int i=0; i<15; i++) {
for(int j=0; j<20; j++) {
cout<< x[i][j] <<" "; }
cout << "\n"; }
}
void cambiar0(int x[][20]){ int n[255];
for (int i=255; i>=0; i--)
n[255-i]=i;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
for(int k=0; k<255; k++)
if(x[i][j]==n[k]) {
x[i][j]=k; break; }
}
int main(int argc, char* argv[]){
int x[15][20]; char a;
for(int i=0; i<15; i++)
for(int j=0; j<20; j++)
x[i][j]=rand()%255;
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
cambiar0(x);
cout << "\n\n";
cout << "¿desea ver la matriz? s/n ";
cin >> a;
if(a=='s') ver(x);
system("PAUSE"); return 0;
}
///////////////////////////////////
Hope this is what you meant.
arr is a pointer to the multi-dimesional array you have and is actually a pointer to an int. Now since your function accepts a pointer to an int pointer, you need to get the address of arr using: &arr and pass that to the function so that you will have this code:
To coerce the array: Pass &arr to the function.
To reference the array inside the func: *maze[x][y]