Copy pointer content to stack variable - c++11

I have this doubt that came to my mind. Is this possible?
Consider this code:
int* p;
int j = 9;
p = &j;
// is it possible to declare int x and store inside 9?
// so if I do delete p; that value is stored in x
Thanks in advance and regards

You can definitely read the value that p refers to and copy it into another int like this:
int x = *p;
// The value has been copied, j and hence *p aren't affected by changes to x:
++x;
assert(x > *p);
However, you definitely don't want to delete p, because it's not heap-allocated with new. Instead, p points to j, and j has a lifetime automatically managed by the surrounding scope.

Related

why the difference between two pointers pointing to different elements of an array is the no of elements between these two pointers?

int main()
{
int arr[]={2,3,5,6,8};
int *ptr;
ptr=&arr[3];
cout<<ptr-arr;
}
Q.why the answer is 3 after compiling the code i.e. as it should be 3*sizeof(int) which in this case should be 3*4=12?
When you subtract pointers you get the distance between them, not the allocated size. The same goes for iterators in STL.
https://en.cppreference.com/w/cpp/language/operator_arithmetic#Additive_operators
The reason is that it is much easier to write correct code.
When the pointer difference between consecutive elements of an array is 1, then you can use ++p to walk through the array (assuming p is a pointer to an element). For example:
int a[10];
for (auto p = a, e = a + 10; p != e; ++p)
*p = 42;
Notice how the code does not have to deal with the size of the elements. If the array type changes from int to double, the code does not have to change and is still correct.

how typecasting & dereferencing works here?

#include<stdio.h>
int main(){
int a, b, c;
char *p = 0;
int *q = 0;
double *r = 0;
cout<<(int)(p + 1); // printing 1 char size
cout<<(int)(q + 1); // printing 4
cout<<(int)(r + 1); // printing 8
int y = 9;
int *u = &y;
cout<<(int)(u+1); //printing 7208688
cout<<*(p+1); //not able to dereferance
}
How is type-casting working in both the above case?
Why pointers p, q, r are unable to dereference?
Dereferencing any of p, q, r, p + 1, q + 1, r + 1 or u + 1 has undefined behaviour, because none of those pointers point to objects of the correct type.
You can add to a pointer, to get a different pointer value. This is only defined for results that stay within the same array, plus the "one-past-the-end" pointer value (treating a pointer to a single object as an array of length one). You can also convert a pointer to an integer type, to get an implementation defined value. Doing those things does not involve dereferencing the pointer.
Adding to a null pointer is also undefined behaviour, because the null pointer does not point to an object, there is nothing to be "one-past-the-end" of.

Eigen - return type of .cwiseProduct?

I am writing a function in RcppEigen for weighted covariances. In one of the steps I want to take column i and column j of a matrix, X, and compute the cwiseProduct, which should return some kind of vector. The output of cwiseProduct will go into an intermediate variable which can be reused many times. From the docs it seems cwiseProduct returns a CwiseBinaryOp, which itself takes two types. My cwiseProduct operates on two column vectors, so I thought the correct return type should be Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr>, but I get the error no member named ColXpr in namespace Eigen
#include <RcppEigen.h>
// [[Rcpp::depends(RcppEigen)]]
Rcpp::List Crossprod_sparse(Eigen::MappedSparseMatrix<double> X, Eigen::Map<Eigen::MatrixXd> W) {
int K = W.cols();
int p = X.cols();
Rcpp::List crossprods(W.cols());
for (int i = 0; i < p; i++) {
for (int j = i; j < p; j++) {
Eigen::CwiseBinaryOp<Eigen::ColXpr, Eigen::ColXpr> prod = X.col(i).cwiseProduct(X.col(j));
for (int k = 0; k < K; k++) {
//double out = prod.dot(W.col(k));
}
}
}
return crossprods;
}
I have also tried saving into a SparseVector
Eigen::SparseVector<double> prod = X.col(i).cwiseProduct(X.col(j));
as well as computing, but not saving at all
X.col(i).cwiseProduct(X.col(j));
If I don't save the product at all, the functions returns very quickly, hinting that cwiseProduct is not an expensive function. When I save it into a SparseVector, the function is extremely slow, making me think that SparseVector is not the right return type and Eigen is doing extra work to get it into that type.
Recall that Eigen relies on expression templates, so if you don't assign an expression then this expression is essentially a no-op. In your case, assigning it to a SparseVector is the right thing to do. Regarding speed, make sure to compile with compiler optimizations ON (like -O3).
Nonetheless, I believe there is a faster way to write your overall computations. For instance, are you sure that all X.col(i).cwiseProduct(X.col(j)) are non empty? If not, then the second loop should be rewritten to iterate over the sparse set of overlapping columns only. Loops could also be interchanged to leverage efficient matrix products.

How to construct a 2-dimensional array in ATS?

For instance, I am looking for an example in ATS that does more or less what the following C code does:
int *theMultable[10][10];
void
theMultable_initialize()
{
int i, j;
for (i = 0; i < 10; i++)
{
for (j = 0; j < 10; j++) theMultable[i][j] := i * j;
}
return;
}
One possible approach is to attempt a direct translation to C. However, I now think that I should have used builtin matrix type instead. This code relies on quite a bit of advanced functionality (I even left one unproven lemma for exercise: it shows that N*sizeof(T) == sizeof(#[T][N]).
The loop to initialize a 2-dimensional array is implemented in the function:
extern
fun
multable_init (
mat: &(#[#[int][10]][10])? >> _
): void // end of [multable_init]
This function, in turn, uses two functions (both initialize an array of elements, basically). Also, the global variable multable is allocated, and is then initialized using multable_init (I thought it wouldn't work, but it did!).
Here's the code of initialization of the global variable:
var multable : #[int?][100]
val p_multable = addr#multable
prval pf_multable = array_v_group (view#multable)
val () = multable_init (!p_multable)
prval pf_multable = array_v_ungroup (pf_multable)
prval pf_multable = array2matrix_v (pf_multable)
val theMultable = ref_make_viewptr {matrix (int, 10, 10)} (pf_multable | p_multable)
A mutable array is allocated on stack, then we take its address (line 2), turns its corresponding at-proof from #[int?][100] to #[#[int?][10]][10] (via grouping on line 3), and initialize it. Then, we turn the grouped-array view into a matrix view, and finally, put it into a ref-cell.
The full code is at Glot.io

swaping inplace

how to swap two numbers inplace without using any additional space?
You can do it using XOR operator as:
if( x != y) { // this check is very important.
x ^= y;
y ^= x;
x ^= y;
}
EDIT:
Without the additional check the above logic fails to swap the number with itself.
Example:
int x = 10;
if I apply the above logic to swap x with itself, without the check I end up having x=0, which is incorrect.
Similarly if I put the logic without the check in a function and call the function to swap two references to the same variable, it fails.
If you have 2 variables a and b: (each variable occupies its own memory address)
a = a xor b
b = a xor b
a = a xor b
There are also some other variations to this problem but they will fail if there is overflow:
a=a+b
b=a-b
a=a-b
a=a*b
b=a/b
a=a/b
The plus and minus variation may work if you have custom types that have + and - operators that make sense.
Note: To avoid confusion, if you have only 1 variable, and 2 references or pointers to it, then all of the above will fail. A check should be made to avoid this.
Unlike a lot of people are saying it does not matter if you have 2 different numbers. It only matters that you have 2 distinct variables where the number exists in 2 different memory addresses.
I.e. this is perfectly valid:
int a = 3;
int b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
assert(a == b);
assert(a == 3);
The xor trick is the standard answer:
int x, y;
x ^= y;
y ^= x;
x ^= y;
xoring is considerably less clear than just using a temp, though, and it fails if x and y are the same location
Since no langauge was mentioned, in Python:
y, x = x, y

Resources