pointer to an array address minus the address of an array [duplicate] - arrays

This question already has answers here:
Pointer subtraction confusion
(8 answers)
Closed 9 years ago.
I have a pointer to array, why it gives me the following output?
int main() {
int b[] = {1, 2};
cout << "size of int = " << sizeof(int) << endl;
int *pt = b;
int i = 0;
while( i++ < 2) {
cout << "pt = " << pt << ", b = " << b << endl;
cout << pt - b << endl;
(pt)++;
}
return 0;
}
code output:
size of int = 4
pt = 0x7fff576f0c2c, b = 0x7fff576f0c2c
0
pt = 0x7fff576f0c30, b = 0x7fff576f0c2c
1
pt is a pointer to the start of array b initially, why pt-b gives me the index of the array that pt points to rather than the index of the array times the size of one element.

it's because your array is really an address, and int *pt = b; essentially makes pt the exact same as b
your output is simply printing the number of times you've incremented pt since you set it to b

Remember, in the end, pointers are plain old ints, which represent an address in your logical space. Here the address b is pointing to remains constant while pt gets shifted by one.

Related

How the 11th element got added into array if the decalred array is arr[10]?

The code
using namespace std;
int main ()
{
int arr[10], n, i, sum = 0, pro = 1;
cout << "Enter the size of the array : ";
cin >> n;
cout << "\nEnter the elements of the array : ";
for (i = 0; i < n; i++)
cin >> arr[i];
for (i = 0; i < n; i++)
{
sum += arr[i];
pro *= arr[i];
}
cout << "\nSum of array elements : " << sum;
cout << "\nProduct of array elements : " << pro;
return 0;
}
Here, I did not understand how the 11 can be given as input to get the sum and the product
Output sample
Enter the size of the array : 11
Enter the elements of the array : 11 10 9 8 7 6 5 4 3 2 1
Sum of array elements : 66
Product of array elements : 39916800
That's because arrays are actually pointers.
When you create an array, you are basically telling the compiler to reserve enough space to store all elements of the array. When you access the 11th element of the array you are accessing part of the memory that is not reserved for your array, which I think is considered undefined behaviour.
Try the following:
int a = 24;
int b = 24;
int c = 24;
int d = 24;
int arr[0];
int e = 24;
int f = 24;
int g = 24;
int h = 24;
cout << arr[2];
You will probably see the number 24 printed to the screen because you are accessing some memory that is reserved for other variables.
The positions of an array start at 0, so if you start counting from 0, the element in position 10 is on 11

Store result of sparse matrix decomposition in pre-specified memory location, in Eigen

I am trying to write a function to perform a sparse Cholesky decomposition using the Eigen library, where I pass in both the pointers to the input matrix data and the pointers to where I want to store the output matrix.
The program is currently
#include <iostream>
#include <Eigen/Dense>
#include <Eigen/SparseCore>
#include <Eigen/SparseCholesky>
using namespace std;
using namespace Eigen;
struct CSC {
int *indptr;
int *indices;
double *data;
int nnz;
};
int cholesky_sparse_d_c(struct CSC *A, struct CSC *L,
int rows, int cols, int nnz) {
// Find sparse Cholesky factorisation of matrix A and store in triangular
// matrix L i.e A = L L.T.
// First we must build the sparse matrix A.
Map<SparseMatrix <double> > A_sp(rows, cols, nnz,
A->indptr, A->indices, A->data);
cout << "A: " << endl << A_sp << endl;
// Now compute the sparse Cholesky decomposition.
SimplicialLLT<SparseMatrix<double> > SLLT;
SLLT.compute(A_sp);
if (SLLT.info() != Success) {
cout << "Decomposition failed";
return -1;
}
cout << "Sparse lower factor of A:" << endl << SLLT.matrixL()
<< endl;
// Put the values back into L. Note I am not sure if we need to create a
// `temp` variable here, as the call `.matrixL()` may be free.
SparseMatrix<double > temp(SLLT.matrixL());
L->indptr = (int *) temp.outerIndexPtr();
L->indices = (int *) temp.innerIndexPtr();
L->data = (double *) temp.valuePtr();
L->nnz = (int) temp.nonZeros();
Map<SparseMatrix <double> > L_sp(rows, cols, L->nnz,
L->indptr, L->indices, L->data);
cout << "L: " << endl << L_sp << endl;
return 0;
}
int main() {
struct CSC A;
int A_indptr[] = {0, 1, 2};
int A_indices[] = {0, 1};
double A_data[] = {1.1, 2.2};
A.indptr = A_indptr;
A.indices = A_indices;
A.data = A_data;
struct CSC L;
cholesky_sparse_d_c(&A, &L, 2, 2, 2);
cout << L.indptr[0] << L.indptr[1] << L.indptr[2] << endl;
cout << L.indices[0] << L.indices[1] << L.indices[2] << endl;
cout << L.data[0] << L.data[1] << L.data[2] << endl;
}
As mentioned in the code, I am not sure if the temp variable is necessary as
L_indptr = SLLT.matrixL().outerIndexPtr();
L_indices = SLLT.matrixL().innerIndexPtr();
L_data = SLLT.matrixL().valuePtr();
may be fine (I am not sure if matrixL() is a free operation).
Regardless, when this function exits the memory that the L pointers were pointing to will now be free'd. I could copy the memory but this is unnecessary and inefficient. What I would ideally like to do is tell SLLT to not create new pointers for
.outerIndexPtr()
.innerIndexPtr()
.valuePtr()
but to use the pointers in the L structure provided.
Is there a way to do this?
If you insist on saving a copy (it should be very cheep compared to the decomposition), then the simplest and safest would be to keep SLLT alive as long as your L, for instance by creating a small structure storing both objects and being responsible for destroying both of them.
Otherwise, you could imagine moving SLLT.matrixL() into L, but then you'll have to free the allocated memories, but you cannot as you don't know how it was allocated. To allocate yourself L and pass it SLLT, you need a way to exactly know the number of non-zeros in L. Actually, this information is computed by the analyzePattern step, but this method also pre-allocate SLLT.matrixL(), so that's too late.

Updating fields of bits incorrectly

I'm trying to solve a question. It says,
Initialize a new variable to the value 17512807u.
Assume we number the bits as usual from 0 as least significant (on the
right) to 31 (most significant, on the left). Update bits 18 through
21 with the integer value 8 and bits 10 through 14 with value 17
(decimal). Print the resulting value as an eight digit hexadecimal
number to show all of the digits.
Here's the code I came up with:
#include <stdio.h>
int main(){
int value = 17512807u;
int L = 21; // starting left position
int R = 18; // starting right position
int mask = (1 << (L - R + 1) - 1) << R;
int newField = (8 << R) & mask; // integer value 8, shifting to right
int newValue = value & (~mask); // remove range of bits
value = newField | newValue; // update range of bits
L = 14;
R = 10;
mask = (1 << (L - R + 1) - 1) << R;
newField = (17 << R) & mask;
newValue = value & (~mask);
value = newField | newValue;
printf("%08x\n", value);
}
The answer I get is 012b7d67
However, I am told this is the incorrect answer. I do not know what the correct answer is.
int mask = ((1 << (L - R + 1)) - 1) << R;
Your expressions to compute mask are incorrect. You changed the parentheses in the second expression but both are incorrect, and do not even compile:
int mask = ((1 << (L - R + 1) - 1) << R;
...
mask = ((1 << (L - R + 1) - 1 << R);
should be written:
mask = ((1UL << (L - R + 1)) - 1) << R;
Looks like what you are asked to do is use the bit fields. For example, given the type
struct bits{
int a:5;
unsigned short b:3;
unsigned char c:2;
bool d:1;
};
The above struct will have 4 members, each of specific bit length.
If you union that struct with an int you get a "dual-view" of the bits. As a list of fields or as a single integer:
union U{
struct bits fields;
int i;
};
Now the code like
U u;
u.i = 0;
u.fields.b = true;
becomes valid and gives you access to either the whole number or individual bit fields.

A more faster (optimized) solution to image decimation (C++)

I am looking for a more faster way of dealing with the following C code. I have an image of 640x480 and I want to decimate it by a factor of 2 by removing every other rows and columns in the image. I have attached the code in the following. Is there any better way to optimize the code.
#define INPUT_NUM_ROW 480
#define INPUT_NUM_COL 640
#define OUTPUT_NUM_ROW 240
#define OUTPUT_NUM_COL 320
unsigned char inputBuf[INPUT_NUM_ROW* INPUT_NUM_COL];
unsigned char outputBuf[OUTPUT_NUM_ROW* OUTPUT_NUM_COL];
void imageDecimate(unsigned char *outputImage , unsigned char *inputImage)
{
/* Fill in your code here */
for (int p = 0; p< OUTPUT_NUM_ROW; p++) {
for (int q = 0; q < OUTPUT_NUM_COL; q++) {
outputImage[p*OUTPUT_NUM_COL + q] = inputImage[(p*INPUT_NUM_COL+q)*2];
// cout << "The pixel at " << p*OUTPUT_NUM_COL+q << " is " << outputImage[p*OUTPUT_NUM_COL+q] << endl;
}
}
}
Rather than doing the math every time in the inner loop, you could do this:
int outputIndex;
int inputIndex;
for (int p = 0; p< OUTPUT_NUM_ROW; p++) {
inputIndex = p * INPUT_NUM_COL * 2;
outputIndex = p * OUTPUT_NUM_COL;
for (int q = 0; q < OUTPUT_NUM_COL; q++) {
outputImage[outputIndex] = inputImage[inputIndex];
inputIndex += 2;
outputIndex++;
// cout << "The pixel at " << p*OUTPUT_NUM_COL+q << " is " << outputImage[p*OUTPUT_NUM_COL+q] << endl;
}
}
}
You could do the incrementing inline with the copying assignment too, and you could also only assign inputIndex and outputIndex the first time, but it wouldn't get you as much of a performance boost as moving the calculation out of the inner loop. I assume that bulk copying functions don't have this kind of incrementing flexibility, but if they do and they use hardware acceleration that is available on all of your target platforms, then that would be a better choice.
I am also assuming that array access like this compiles down to the most optimized pointer arithmetic that you could use.

accessing bytes of an integer in c

i have values like 12, 13 which i want assign to single integer example, k.
i tried the following program but i am not getting expected results.
enter code here
#include <stdio.h>
int main()
{
int k = 0;
printf("k address is %u\n", &k);
char* a = &k;
printf("%u\n", a);
*(a) = 12;
a++;
printf("%u\n", a);
*(a) = 13;
printf("k is %d\n",k);
return 0;
}
and the output is:
k address is 3213474664
3213474664
3213474665
k is 3340
On your system, ints are evidently stored in little-endian format, because 13*256 + 12 = 3340.
If you want to modify bytes in an integer in an endian-independent way, you should use shifts and bitwise operators.
For example, if you were trying to store an IP address of 1.2.3.4 into a 32-bit integer, you could do:
unsigned int addr = (1 << 24) | (2 << 16) | (3 << 8) | 4;
This guarantees that 1 is the most significant byte and so forth.

Resources