I am working on a paint program and i create an array of figures in a class
and i want to pass that array to another class and loop through it's elements
i dont understand the problem
the main class:
CFigure* FigureList[Figcount];
CFigure* getfiglist()
{
return *FigureList;
}`
and the other class include:
CFigure *P=pManager->Getfiglist();
for(int i=0;i<pManager->Getfigcount;i++)
{
*(p+i)->resize(factor); //displays error : operand of * must be a pointer
}
how should i access the array elements using the passed pointer and what did i do here that caused the error . thanks in advance
There is a lot to say about arrays in C++, here is some information that might help :
Native C++ arrays
if you create an array like so :
int array[10] = {0,1,2,3,4,5,6,7,8,9};
And you try to print the values of array, &array or &array[0] you will notice they are all the same values. This value is the adress of the first element in your array. There is no such thing as an array pointer, there is just a pointer to the first element.
As the other elements of your array follow the first, you can access them by adding 1 to the address of the first element (array+1) :
void print(int *array, int length)
{
for (int i=0 ; i<length ; i++){
cout << *(array+i) << endl;
}
}
int main()
{
int array[10] = {0,1,2,3,4,5,6,7,8,9};
print(array, 10);
}
It turns out that you can also use the regular expression to access your array elements and it will work fine :
void print(int *array, int length)
{
for (int i=0 ; i<length ; i++){
cout << array[i] << endl;
}
}
Vectors
That being said, if one is not careful with native arrays, the code may quickly get very nasty and hard to read... This is why you should use std::vector instead as suggested by #Ðаn.
Vectors have the particularity to be dynamic so you don't have to specify any size when you create them, and you can add as many elements as you want without caring about any pointer or memory stuff.
void print(vector<int> &v)
{
for (int i=0 ; i<v.size() ; i++){
cout << v[i] << endl;
}
}
int main()
{
vector<int> v = {0,1,2,3,4,5,6,7,8,9};
v.push_back(10);
v.push_back(11);
v.push_back(12);
print(v);
}
Links
You can read more about vectors here.
I didn't talk about it but there is also std::array.
Related
I am a C++ beginner and my task is as follows:
Define and initialise a single-dimensional integer array. Next, define a pointer that points to the first element in the array and passes the pointer to a function.
Using only pointer variables (and looping constructs), print only the array values that are exact multiples of 7 from start to finish to standard output. The only program output should be the numbers, one per line with no white space.
I have tried:
void print_sevens(int* nums, int length)
{
int array[5] = { 5,8,21,43,70 };
int* ptr = array;
int* num = array;
for (int i = 0; i < length; i++)
{
*num++;
if (num[i] % 7 == 0) {
cout << num[i] << endl;
}
}
}
int main()
{
int array[5] = { 5,8,21,43,70 };
int* ptr = array;
print_sevens(ptr, 5);
}
It compiles but does not output anything.
I am also confused about passing the pointer to a function. Should this be done in the main file or in the function file?
You are creating an additional array in the print_sevens function, which is unnecessary as you already passed the pointer to the first element of the array created in the main()(i.e. array).
Removing that unnecessary array and related codes from the function will make the program run perfectly. (See online)
void print_sevens(int* nums, int length)
{
for (int i = 0; i < length; i++)
{
if (nums[i] % 7 == 0)
std::cout << nums[i] << std::endl;
}
}
and in the main you only need to do the follows, as arrays decay to the pointer pointing to its first element.
int main()
{
int array[5]{ 5,8,21,43,70 };
print_sevens(array, 5);
}
Note that,
num++ increments the pointer, not the underline element it is
pointing to (due to the higher operator precedence of operator++ than operator*). If you meant to increment the element(pointee) you
should have (*num)++.
Secondly, do not practice with using namespace std;. Read more:
Why is "using namespace std;" considered bad practice?
You are modifying the contents of your array when you do *num++.
I want to declare a 2D Array without an initial size. It keeps on giving me an error:
Error C2078: too many initializes.
I have tried to dynamically allocate my array but nothing worked out so far as I am not too familiar with dynamic allocation. My question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?
I wrote a simple program using pointers, new and delete functions. You can add more functionality to it.
#include <iostream>
using namespace std;
int main()
{
int size;
cout << "Input size of 2D array : ";
cin >> size;
int *ptr; // Declare Pointer
ptr = new int[size*size]; // Allocate memory of all elements in 2D array
for (int i = 0; i < size*size; i++) {
*(ptr + i) = 0; // Initialize every element to 0
}
cout << "Printing the 2D Array" << endl << endl;
int iterSize = 0;
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
cout << *(ptr + iterSize) << " ";
}
cout << endl;
}
delete [] ptr; // ptr memory is released
return 0;
}
Here is the output initializing all elements to 0:
my question is If there is a possible way to declare an Array without an initial size and if so what is the most efficient way to do it ?
Sure, you could provide a vector of vectors to represent a 2D array (let's say of integer values):
std::vector<std::vector<int>> my2DArray;
Well, regarding efficiency maybe performance and memory fragmentation wise it's better to wrap a 1D vector kept internally with an interface that allows 2D coordinate access.
That would require you to know and specify the dimension limits though.
So if you really want to keep a 2D structure without initial size the above mentioned vector of vectors is the way to go.
Beginner c++ programmer, writing code to solve Sudoku puzzles. I'll keep the background info short to avoid confusion.
I have an array of pointers, int *P[9], I have assigned each entry a specific address. I want to assign these addresses to another array of pointers, int *B[81].
P[0] should correspond to B[0], P[1] to B[8], and so on.
When I pass these to a function:
void (int B[ ], int P[ ] ) {...}
it seems like the function is converting the address P[ ] is pointing to into an integer value. Before the function is called P[0] points to the address 0x7fff978d46b0, if I check the value of P[0] inside the function it's a number like `48782346 .
#include<iostream>
using namespace std;
void assign_box(int matrix[], int P[])
{
cout << "P[0] in function: " << P[0] << "\n";
matrix[0]=P[0];
}
int main()
{
int table[9][9];
//Initialise table entries to 0
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
table[i][j]=0;
}
}
//Assign addresses to vector P, for brevity P is of length one
int *P[1];
P[0]=&table[0][0];
cout<< "P[0] before function: " << P[0] << "\n";
int*B[81];
assign_box(B[81], P[9]);
}
If it did this and worked I wouldn't care, but unfortunately when I assign B[0] = P[0], it hits me with a Segmentation fault (core dumped), which makes me wonder is the function trying to assign the pointer B[0] to the address 48782346.
Is it possible for the function to convert an address into an integer value?
Apologies if my question is unclear or verbose, first time asker. And thank you for edits.
If you dereference int*[] (or int**), you get an int*. If you dereference an int*, you get an int. This is exactly what you are doing, and why you end up with an int at the end.
//main
int *P[1]; //Array of pointers to int
int *B[81]; //Array of pointer to int
assign_box(B[81], P[9]); //Pass in two pointers to int
//assign_box
matrix[0]=P[0]; //assign int to int
You probably meant to call assign_box like assign_box(B, P), and have the signature be void assign_box(int *B[], int *P[]);. This would then allow you to assign one pointer inside an array to another pointer inside an array.
There are multiple things that could be causing segmentation faults, but they all stem from invalid array indices. If an array is declared like type identifier[size];, it has valid indices from 0 to size - 1. So, int *B[81]; means B[81] is invalid.
You're passing in the wrong parameters. You're trying to pass in an array object B[81] which does NOT EXIST. You only have B[0] - B[80]. Also, B[80] isn't an int pointer. It's an int within an int array. P[9] is a pointer to an array of integers. So, you're trying to pass an integer in an array slot that does not exist into a parameter that does not take integers -- it takes integer arrays.
#include<iostream>
using namespace std;
void assign_box(int matrix[], int P[])
{
cout << "P[0] in function: " << P[0] << "\n";
matrix[0]=P[0];
}
int main()
{
int table[9][9];
//Initialise table entries to 0
for(int i=0; i<9; i++)
{
for(int j=0; j<9; j++)
{
table[i][j]=0;
}
}
//Assign addresses to vector P, for brevity P is of length one
int *P[1];
P[0]=&table[0][0];
cout<< "P[0] before function: " << P[0] << "\n";
int*B[81];
assign_box(B[81], P[9]); // WRONG
}
I was trying to dig more into using arrays and pointers while I came across this problem:
main.cpp:13:7: error: cannot convert 'int [2][5][10]' to 'int*'
in assignment show=ary;
Here's the code:
#include <iostream>
using namespace std;
void arrayLearn(int *);
int main()
{
int ary[2][5][10];
int *show;
ary[2][4][9]=263;
ary[2][5][10]=100;
show=ary; //line 13
arrayLearn(show); //line 14
cout <<"End process"<<endl;
return 0;
}
void arrayLearn(int *arg)
{
for(int i=0;i<100;i++)
{
cout<<"Pointer position: "<<i<<" Value: "<<*(arg++)<<endl;
}
}
If I remove the line 13 and replace line 14 with the following code,
arrayLearn(ary[5][10]);
then the program compiles, but I don't understand why I should pass only two dimensions and not three. If I'm passing the pointer to the first item in the array then why can't I just pass the pointer like this?
arrayLearn(ary);
Please let me know if I've missed some vital concepts or failed to see a really simple mistake.
As Abhishek stated, you are trying to pass a 3-dimensional array to a 1-dimensional object.
If the show variable is not used anywhere else, you can do the following:
#include <iostream>
using namespace std;
void arrayLearn(int *);
int main()
{
int ary[2][5][10];
// Code change explained below (see Note)
ary[1][4][8] = 263;
ary[1][4][9] = 100;
// Pass the starting address of the array
arrayLearn(&ary[0][0][0]);
cout <<"End process"<<endl;
return 0;
}
// Iterate through the array using the position of the elements in memory
void arrayLearn(int *arg)
{
for(int i=0;i<=100;i++)
{
cout<<"Pointer position: "<<i<<" Value: "<<*(arg++)<<endl;
}
}
Output:
...
Pointer position: 98 value: 263
Pointer position: 99 value: 100
End process
This way allows you to pass the starting address of the array to the function.
Note: It should be noted that your original array assignments ary[2][4][9] = 263; and ary[2][5][10] = 100; are outside the bounds of the array. Array indexes start at 0. So even though you have declared your array as ary[2][5][10]; To access the last array element, you would use ary[1][4][9];.
If you are willing to use std::vector, which I highly recommend, you can use the following code to create a 2D vector:
using std::vector<int> Vec1;
using std::vector<Vec1> Vec2;
using std::vector<Vec2> Vec3;
Vec3 a(2, Vec2(5, Vec1(10, 0));
and then change the argument of arrayLearn to const Vec3& to call it using a.
void arrayLearn(const Vec3& arg)
{
// You'll need to use three loops to traverse all the elements.
for ( auto const& v2 : arg )
{
for ( auto const& v1 : v2 )
{
for ( auto const& item : v1 )
{
// Use item
}
}
}
}
In simple terms, ary is 3-Dimensional and show is 1-Dimensional. The compilation errors tell you that you can't convert 3D into 1D. Now, why does following work?
arrayLearn(ary[5][10]);
It is because, ary[5][10] is referring to 1D (a row or a column or a height, depends on how you visualize 3D array) and arrayLearn is also accepting 1D parameter.
if you want to pass ary using show then pass 2D like ary[5][10] to show variable, something like following :)
show = ary[5][10];
you can use STL data structurs like vector, map , linkedlist , ...
that all of them are better that array both in emplementation and in performance.
but for solving exactly this problem, you must pass 3 dimention array to one function in this manner:
int array[10][7][8];
void function_sample(int (*a)[7][8] , int length)
{
//for example for printing array cells
for(int i =0 ; i< length ; i++)
{
for(int j =0 ; j< 7 ; j++)
{
for(int k =0 ; k< 8 ; k++)
{
cout << a[i][j][k] << endl
}
}
}
//....
}
and for calling this function :
int array[10][7][8] //= {initial your array};
function_sample(array , 10);
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]