Finding main diagonal matrix using pointer array - c++

I'm new to c++,
I'm trying to find main diagonal matrix using pointer array like
int * ProblemSolution :: solution(int *A,int N)
{
//write your code here
for (int m=0;m<N;m++){
for (int x=0;x<N;x++){
if(m=x)
cout<<*(*(A+m)+x)<<",";
}
}
return 0;
}
but i'm getting some kind of error:
can anyone help me?

You have a few problems
if(m=x)
is an assignment, you probably want,
if(m==x)
Square bracket syntax is a lot clearer than pointer arithmetic,
A[m]
instead of,
*(A+m)
Also *(A+m) is an integer, so *(A+m)+x is also an integer which you can't dereference.
Your index should be something like:
A[m*N+x]

A is an int*
A+m is also an int*
*(A+m) is an int
(*(A+m) + x) is also an int
Instead of cout<<*(*(A+m)+x)<<","; you could write int tmp = (*(A+m)+x); cout << *tmp << ",";.
You are trying to derefence a pointer.
To make things easier you should rather use appropriate types (e.g. std::array, std::vector) instead of using raw-pointers.

*(*(A+m) + x) is an int,So try to store it in some variable then print it. Also you are mixing up 2D matrix(pointer to pointer) with 1D array(pointer).
try to do like-
*(A+m)=A[m] ,
*(*(A+m)+x) =A[m][x]

You mixed up 2D matrix represented by pointer to pointer and 1D array represented by pointer, your case is the latter.
*(*(A+m)+x) is legal only if A is a pointer to array decayed to a pointer to pointer, instead it should be *(A + N*m +x)

Related

C++ referencing an array of structs

I'm new to using C++ for complicated programming. I've been sifting through some leftover, uncommented, academic code handed down through my department, and I've stumbled across something I have no real idea how to google for. I don't understand the syntax in referencing an array of structs.
Here is a trimmed version of what I'm struggling with:
typedef struct
{
double x0,y0;
double r;
} circle;
double foo()
{
int N = 3;
double mtt;
circle circles[N];
for (int i = 0; i < N; i++)
{
mtt += mtt_call_func((circles+i), N);
}
return mtt;
}
What does (circles+i) mean in this case?
EDIT: the function should have (circles + i), not (circle + i).
circles+i is equivalent to &circles[i]. That's how pointer arithmetic works in C++.
Why is there a pointer? Well, when you give the name of an array, in a context other than &circles or sizeof circles, a temporary pointer is created that points to the first member of the array; that's what your code works with. Arrays are second-class citizens in C++; they don't behave like objects.
(I'm assuming your circle+i was a typo for circles+i as the others suggested)
circle+i means "take a pointer circle and move it i times by the size of the object pointed to by it". Pointer is involved because the name of the array is a pointer to it's first element.
Apart from this you should initialize an integer counter variable that is used in loop:
for (int i = 0; i < N; i++)
^^^^
{
mtt += mtt_call_func( ( circles + i), N);
^ // typo
}
In C, as in C++, it is legal to treat an array as a pointer. So circles+i adds i times the size of circle to the address of circles.
It might be clearer to write &circles[i]; in this form, it is more obvious that the expression produces a pointer to the ith struct in the array.
Each vector you declare in stack it's actually a pointer to the first index, 0, of the vector. Using i you move from index to index. As result, (circles+i) it's the equivalent of &circles[i].
& means the address of the variable. As in your function call, you send a pointer which stores an address of a variable, therefore & is required in front of circles[i] if you were to change to that, as you need the address of the i index of the vector circles to run your function.
For more about pointers, vectors and structures check this out: http://pw1.netcom.com/~tjensen/ptr/pointers.htm
It should cover you through ground basics.

Cannot convert double [] [] to double **

I ve got a function that takes 3 parameteres, first one is **double.
normalizeDataZeroMeanUnitSD(double ** trainingActions, int numberOfTrainingActions, int descriptorDimension)
When I call it from main, I am trying to use normalizeDataZeroMeanUnitSD(data, 681, 24); however, I am receiving
cannot convert parameter 1 from 'double [681][24]' to 'double **'
This is how I construct the data array:
fstream infile;
infile.open("gabor\\Data.txt");
double data[681][24];
while (!infile.eof())
{
for(int j=0;j<681;j++)
{
for(int k=0; k<24;k++)
{
infile >> data[j][k];
}
}
}
infile.close();
Is there a way to do the same using **data?
The error is pretty clear: Datatype double [681][24] is not the same as double **. While it's true that double[681] can decay to a pointer to its first element (thus, double*), that does not imply that double[681][24] can decay to double**.
Think about it this way: double** implies a pointer to many pointers. But double[][] does not have ANY pointers in it. At best, an array of ANY dimensions still only has, at very most, one pointer: to the beginning of its contiguous storage.
You could use a template:
template<std::size_t M, std::size_t N>
void normalizeDataZeroMeanUnitSD(double (&trainingActions)[M][N], int descriptorDimension)
{
for( std::size_t m = 0; m < M; ++m )
{
for( std::size_t n = 0; n < N; ++n )
{
trainingActions[m][n] = ...;
}
}
}
But beware of code bloat if you call this with many differently sized arrays.
Use any of the following declarations. Both are equivalent.
NormalizeDataZeroMeanUnitSD(double trainingActions[][24], int numberOfTrainingActions, int descriptorDimension)
NormalizeDataZeroMeanUnitSD(double trainingActions[681][24], int numberOfTrainingActions, int descriptorDimension)
When you declare a 2D array it takes up contiguous memory locations. So you need to specify at least the number of columns (in case of row major architecture).
For row major and column major definitions, have a look at this.
For your edited question, yes you can declare using **data. Dynamically allocate the data array. But remember to free it when you're done with it.
double **data=new double*[681];
for (int i=0;i<681;i++)
{
data[i]=new double[24];
}
//do what you want to do
for (int i=0;i<681;i++)
{
delete [] data[i];
}
delete [] data;
Now your function prototype can be like void func(double **pp) because data is a pointer not a 2D array.
A 2d array is a continuous area of storage. The function expects a pointer to pointers. These are incompatible.
The function expects an array of pointers to arrays; you have an array of arrays. Some options are:
change the function to take a more friendly type, perhaps double* pointing to the first element of a contiguous 2-dimensional array; or
build a separate array of pointers pointing to each row of your 2-dimensional array; or
restructure your data into an array of pointers to arrays.
Here is a constructive answer for how to make it work.
Basically, you need to generate an array that has pointers to each 1D slice of your 2D array.
double data[N][M] = {...};
double *dataPtrs[N];
for(size_t n=0; n<N; ++n) {
dataPtrs[n] = data[n];
}
normalizeDataZeroMeanUnitSD(dataPtrs, N, M); // order of N and M might be wrong
Yay, I get to rant about this again.
In C++, despite having similar syntax, 2D arrays are NOT jagged arrays. 2D arrays (double foo[681][24]) are allocated contiguously in memory. When you deference a 2D array (foo[j][i]) it actually does *(foo+24*i+j). This is all done under the hood. The sizeof(foo)==sizeof(double)*681*24.
Jagged arrays are (double** bar;). This is a bunch of different arrays: first, you allocate an array of pointer, 268 members long. Each pointer will point to an array of doubles, 24 elements long. Bar is just a pointer, so sizeof(bar)==sizeof(void*).
More annoyingly, 2D arrays (or a static array of any dimension) behave the opposite of all other types in C++ in the following reguard: they are passed implicitly by reference, causing the weird phenomenon below.
void foo(double bar[24][24]) { std::cout << sizeof(bar) << std::endl;}
int main() {
double test[24][24];
std::cout << sizeof(test) << std::endl;//returns sizeof(double)*24*24
foo(test);//returns sizeof(void*), implicitly passed by reference, opossite of the rest of c++!
double[][] is not the same thing as double**.
double** is a pointer to pointers.
double[][] is a 2-dimensional array allocated as continuous storage.
In order to pass a "2-dimensional array" to the function, you need to create an array of pointers to arrays. For example:
double* array_2d[681];
for(unsigned int i=0; i<681; ++i) {
array_2d[i] = new double[24];
}
normalizeDataZeroMeanUnitSD(array_2d, 681, 24);
Remember to later delete[] each element of array_2d!
Better yet, change normalizeDataZeroMeanUnitSD to take a reference to std::vector<std::vector<double>>, and you no longer have to worry about memory management, nor passing the correct dimensions to the function.

How to use (2d) arrays with negative index?

In 1D you can simulate x-coordinate in such a way:
int temp[1000];
int *x = a+500;
How can we have a grid now? (Something like a[10][-13].)
You can easily convert -ve and +ve integers into just +ve integers as an index into an array as you are unable to use -ve indexes.
Here is how
if (index < 0)
then index = -index * 2 - 1
else index = index * 2
i.e. -ve indexes use the odd numbers, +ve use the even numbers. 0 stays at 0.
Don't confuse mathematics with array dimensions in C/C++, those are different things. If you have a mathematical matrix with indices -500 to 500, you use a C array with indices 0 to 1000 to store it in.
However you can access an array by using a negative index, as long as you make sure you aren't accessing the array out of bounds. For example:
int arr[1000];
int* ptr = &arr[499];
printf("%d", ptr[-100]);
2D arrays work in the very same way, although strictly speaking you can still not access a sub array out of bounds and expect to end up in an adjacent array, this is undefined behavior in C/C++. But in real world implementations static 2D arrays are always allocated using adjacent memory cells, so one can often safely assume they are, no matter what the C standard says.
You just have to calculate the offsets yourself, for instance
int grid[400]; // twenty by twenty grid, origin at (10, 10)
int get_grid_value(int x, int y)
{
return grid[20*(x + 10) + (y + 10)];
}
Of course in real code you shouldn't use so many magic numbers.
First of all, this only works if the memory allocated for the array is contiguous. Then you can find out the "middle point" of the array by
int temp[5][5];
int *a = temp[2] + 2;
Or, in more general terms
int len
int *temp = malloc(len * len * sizeof(int));
int *a = temp + (len/2)*len + len/2;
If you want to simulate geometry using arrays ... you could do something like
have a variable with maximum number of points and assign a pointer to the middle value. So with that pointer you could have negative indeces.
A sample program.
int main() {
int c[10000];
int *a = &c[5000];
for(int i=-5000;i<5000;i++)
a[i] = i;
for(int i=-5000;i<5000;i++)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
Hope this was helpful ..
To use it in a more proper way, you could have a class which internally manages this. Or you could have your template.
I'm not sure you can do that with a simple 2-D array without invoking the gremlins of undefined behavior, but you could set it up as an array of pointers. Create an array of pointers to int, then set a pointer to point into the middle of the array; that gives you signed indices for the first dimension. Then set each element of the pointer array to point to an array of int, and advance each to point to the middle of that array; that gives you signed indices for the second dimension. You can use the same arr[x][y] syntax you'd use for an actual 2-D array, but the second [] applies to an actual pointer, not an array that decayed to a pointer.
If any of these arrays are allocated with malloc(), you must pass the original pointer to free().
If there's sufficient interest, I'll try to post some code later.
BTW, I'm not at all convinced this would be worth the effort. You could easily fake all this with ordinary 0-based arrays, at the cost of a little syntactic sugar.

pass a 2D array from a C++ class to a CUDA function

I am a Java guy jumping into CUDA and the syntax is tripping me. I'm trying to create a matrix in the .cpp file then pass that off to the .cu file to be processed. I see examples where the CUDA function expects the 2D array to come in looking like
void handleMatrix(float* A){
// do stuff
}
when I create the matrix I'm used to doing it in code that looks like this:
int main()
{
const int row=8;
const int column=8;
int rnum;
srand(time(0));
rnum = (rand() % 100) + 1;
float table[row][column];
for(int r=0; r<row; r++){
for(int c=0; c<column;c++){
table[row][column] = (rand()%100) + 1.f;
}
cout << "\n";
}
handleMatrix(table);
return 0;
}
When I compile the code I'm getting the error
cannot convert ‘float ()[8]’ to ‘float*’ for argument ‘1’ to ‘void handleMatrix(float*)’*
Is there a different way I should be declaring the matrix or creating it?
Thanks in advance for the help.
You can do
handleMatrix(table[0]);
or, equivalently,
handleMatrix(&table[0][0]);
That's if 'handleMatrix' is host code. If it's device code, you can't allocate the buffer like that. You'll want to assemble an array in local memory, fill the entries, allocate another array in the device memory using cudaMalloc() or cudaMallocPitch(), and then copy from local to device using cudaMemcpy() or cudaMemcpy2D().
You want a pointer to an array. The syntax for declaring a pointer to an array is
void handleMatrix(float (*A)[8][8]) {
// do stuff
}
That is, when you dereference A, you get a reference to an 8 by 8 array of floats.
Even for 1D arrays, there is a distinction between pointer to array (float (*anArray)[100]) and pointer to element (float *anArray). C++ will transparently convert the former to the latter, which means that for 1D arrays (but not arrays of higher dimension) you can usually ignore the difference.
In your example, table[0] converts to a valid float* pointer to 64 consecutive float numbers. But it looks highly suspicious that handleMatrix takes a pointer meant to be an array and doesn't take any information about the dimensions of that array.
the handleMatrix() function, is this a function from you or is part of a library? If the latter you may need to create the 2-d array as a long row x col 1-d array. If the former you need to change the function to accept a 2-d array e.g. handleMatrix(float**m) and pass the dimensions of the matrix to the function;
preferably though you should use vector<> when programming in C++ then the dimensions are known by the callee.
e.g.
#include <vector>
typedef std::vector<std::vector<float > > matrix;
void handleMatrix( matrix& m ) {..}

C++ Inserting 2D array Object into another 2D array Object

In using Dev C++, I a m trying to insert a smaller 2D array object into a larger 2D array object. While attempting to achieve that, I came into compilers errors which I do not know how to solve.
I attempt to insert the smaller Object by making it returning the array's name. Then I attempt to change the values inside the large array with the values of the smaller array.
There two line of code that I have problems with:
int result = smallerArray.extractPiece();
largerArray.extractArray(result);
And within these two lines of codes:
int Piece::extractPiece()
{
return **pieceArray;
}
and
void Grid::extractArray( int** arr )
{
for(int i = 0; i &lt xGrid ; ++i)
{
for (int j = 0; j &lt yGrid ; ++j)
{
squares[i][j] = arr[i][j];
}
}
}
The two of the problems is that "int result" will not hold smallerArray.extractPiece(),
and if i just put "smallerArray.extractPiece()" in largerArray.extractArray(), i still get problems. I attempted to make "int result" a pointer pointer, as "int** result", i still have the same errors.
These are the errors that i get when i try to compile in Dev C++:
In function `int main()';
invalid conversion from `int' to `int**'
initlizing argument 1 of 'void Grid::extractArray(int**)'
[Build Error] [grid test.o] Error 1
Does anyone know whats wrong?
It's precisely this bunch of code:
int result = smallerArray.extractPiece();
largerArray.extractArray(result);
// ...
int Piece::extractPiece() {
return **pieceArray;
}
Trying to pass an int to extractArray, which wants a pointer to a pointer, presumable your dynamic array, and not an int. Try changing it to
int **result = smallerArray.extractPiece();
largerArray.extractArray(result);
// ...
int ** Piece::extractPiece() {
return pieceArray;
}
Only changing result to a pointer to pointer won't work. You of course also have to change what extractPiece returns (changing from int to int**)
Look, always at least for me it was easier to manage 2D arrays internally as 1D arrays where M[i,j]=A[i*N+j] where N is the number of cols (or rows, if the 2D arrays is row-column type). Users may get elements with the i,j indices but my class always store A[M * N] as private data. Passing 1-D pointer arrays is easier than managing 2-D pointer arrays (you can't fall in the pointer-to-pointer syntax which can get messy in some code).,
This is not related to this question, but since I don't know about specific compiler optimization instrinsics, I wonder if M[i,j] gets transformed to A[i] internally to use simpler addressing modes in the generated code.