Const pointers shallow copy - c++

is it possible to copy
MyStruct * const * array1
to
MyStruct * array1
but just as a shallow copy? I need sort it and write back into it and I want changes in array 1 too
EDIT: Im stupid, I overlooked ** at array1 then it makes sense.

I guess you mean const MyStruct * array1?
In any case you can use const_cast to change constness of a pointer:
const MyStruct * array1;
MyStruct * array2 = const_cast<MyStruct *>(array1);
Or
const MyStruct * const array1;
MyStruct * array2 = const_cast<MyStruct *>(array1);

Works for exactly the structure from the question... But, the second array1 replaced with another pointer parray.
Maybe, you qualify this as a deep copy even if it is a shallow copy of the struct?
Then, maybe, the other answer is better.
struct MyStruct {
int i;
int* p;
};
int j=2;
MyStruct st={ 1, &j };
int main() {
MyStruct* parray1(&st);
MyStruct* const* array1(&parray1);
MyStruct * parray=new MyStruct();
parray->i = (*array1)->i;
parray->p = (*array1)->p;
/*
This is essentially the same as
(*parray) = *(*array1);
*/
delete parray;
}
Edit: A second example as discussed in the comments to this answer.
Here we have a non-const pointer to which we successively assign the pointer values from the const pointer-pointer array1.
#include <iostream>
struct MyStruct {
int i;
int* p;
};
int j=2;
MyStruct st1={ 1, &j }, st2={ 2, &j };
int main() {
MyStruct* parray1[2] = {&st1, &st2};
MyStruct* const *array1(parray1);
std::cout << array1[0]->i << ' ' << array1[1]->i << '\n';
MyStruct* parray=array1[0];
parray->i = 3;
parray=array1[1];
parray->i = 4;
std::cout << array1[0]->i << ' ' << array1[1]->i << '\n';
return 0;
}
The corresponding output:
1 2
3 4
After the last comments (I think) we have reached a common interpretation of the question.
The pointers in the const array are to be copied into a non-const array where they can be re-arranged and the objects can be modified.
#include <iostream>
#include <algorithm>
struct MyStruct {
int i;
int* p;
};
int j=2;
MyStruct st1={ 1, &j }, st2={ 2, &j };
int main() {
MyStruct* parray1[2] = {&st1, &st2};
MyStruct* const *array1(parray1);
std::cout << array1[0]->i << ' ' << array1[1]->i << '\n';
MyStruct* parray[2];
std::copy(array1,array1+sizeof(parray)/sizeof(parray[0]),parray);
// some manipulation:
std::swap(parray[0],parray[1]);
parray[0]->i = 3;
parray[1]->i = 4;
std::cout << array1[0]->i << ' ' << array1[1]->i << '\n';
return 0;
}
The new output is:
1 2
4 3

Related

Pass array of struct pointers to function

Trying to pass array of struct pointers to function doIt() . Looks my way is not correct since I can't get right second array element:
struct c {
int a;
char* b;
};
struct cc {
int a;
c* b;
};
char a[] = "aaa";
char b[] = "bbb";
char e[] = "eee";
c d1 = {1,a};
c d2 = {2,b};
c d3 = { 12,e };
cc g1 = { 123, &d1 };
cc g2 = { 321, &d2 };
cc g3 = { 333, &d3 };
void doIt( c * s)
{
cout << s->b;
s++;
cout << s->b;
}
What is right way to pass array of struct pointers?
Raw arrays in C (and C++) are just pointers. They point to the first element of an array. For example, if you want an array of int, you would write it like int* array. If you want an array of struct c, you would write it like c* array. If you want an array of pointers to struct c, you would write it like c** array.
To access elements, don't use array++, use array[i] where i is the index (position) of the element you want to access, 0 being the index of the first element, 1 the second, etc.
So, your code should look like this:
void doIt(c** s)
{
cout << s[0]->b; // s[0] is the first element
cout << s[1]->b; // s[1] is the second
}
Note that in C++, it is preferred to use std::vector instead of raw arrays.
void doIt(std::vector<c*> s)
{
cout << s[0]->b;
cout << s[1]->b;
}
If you want to pass array to a function you need also pass length of this array:
#include <iostream>
#include <vector>
struct c {
int a;
char* b = nullptr;
size_t size = 0;
};
void doIt(c* all, size_t length);
int main()
{
char a[] = "aaa";
const size_t sizeOfA = sizeof(a)/sizeof(a[0]);
char b[] = "bbb";
const size_t sizeOfB = sizeof(b)/sizeof(b[0]);
char e[] = "eee";
const size_t sizeOfE = sizeof(e)/sizeof(e[0]);
c d1 {1, a, sizeOfA};
c d2 {2, b, sizeOfB};
c d3 {12, e, sizeOfE};
c all[] = {d1, d2, d3};
const size_t length = sizeof(all)/sizeof(all[0]);
doIt(all, length);
return 0;
}
void doIt(c* all, size_t length)
{
if (!all)
{
std::cerr << "Pointer to array is null" << std::endl;
}
for (size_t i = 0; i < length; ++i)
{
for (size_t j = 0; j < all[i].size; ++j)
{
std::cout << all[i].b[j];
}
std::cout << std::endl;
}
}
You can use std::vector. So, you don't need to use adittional argument (length of the vector):
#include <iostream>
#include <vector>
#include <string>
struct c {
int a;
std::string b;
};
void doIt(const std::vector<c>& myVector);
int main()
{
std::vector<c> myVector;
myVector.emplace_back(1, "aaa");
myVector.emplace_back(2, "bbb");
myVector.emplace_back(12, "eee");
doIt(myVector);
return 0;
}
void doIt(const std::vector<c>& myVector)
{
for (size_t i = 0; i < myVector.size(); ++i)
{
std::cout << myVector[i].b << std::endl;
}
}

How to alloc array of pointers to functions usinig new?

Suppose I have a pointer to pointer to function taking int and returning int*.
int* (**ptr)(int) //i hope i'm not wrong here
How should I alloc memory for that pointer using new? And how can I create an array of pointers to functions with new?
I was trying something like this:
int* (**ptr)(int) = new int* (*)(int);
but it shows "expected primary-expression before ‘)’ token"
Here is a demonstrative program that shows how the array can be declared with a typedef and without a typedef.
#include <iostream>
int * func1(int value)
{
static int x = value;
return &x;
}
int * func2(int value)
{
static int x = value;
return &x;
}
int * func3(int value)
{
static int x = value;
return &x;
}
int main()
{
const int N = 3;
typedef int * (*PFunc)(int);
PFunc *ptr = new PFunc[N] { func1, func2, func3 };
int* (**ptr1)(int) = new ( int* (*[N])(int) ){ func1, func2, func3 };
for (int i = 0; i < N; i++)
{
std::cout << *ptr[i]( i ) << std::endl;
}
std::cout << std::endl;
for (int i = 0; i < N; i++)
{
std::cout << *ptr1[i]( i ) << std::endl;
}
std::cout << std::endl;
return 9;
}
The correct syntax to create an array of functions pointers is as follows:
int* (**ptr)(int) = new (int*(*[5])(int));
This creates an array of 5 function pointers, where each function pointer is of type int *(*)(int).
This can be simplified with a typedef:
typedef int *(*fp)(int);
fp *ptr2 = new fp[5];

Whats the correct way of accessing the array through reference

How do i access the array in the main using the reference arrref
The memory leak in the code below is intended to know valgrind tool.But i am not able to compile the code below
#include <iostream>
int& func();
int main()
{
int &arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
int& func()
{
int *a = new int[10];
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return *a;
}
Thanks
The syntax needed is (&arrref)[1]. That refers to the second element of an array.
But make sure that the reference returned from func indeed refers to the first element of an array with sufficient number of elements.
To communicate clearly that func returns a reference to an array you may like to return a range, e.g.:
#include <iostream>
#include <boost/range/as_array.hpp>
boost::iterator_range<int*> func() {
static int array[2] = {1, 2};
return boost::as_array(array);
}
int main() {
auto array = func();
std::cout << array[0] << '\n';
std::cout << array[1] << '\n';
for(auto const& value: func())
std::cout << value << '\n';
}
Outputs:
1
2
1
2
Firstly it is not a good idea access local variables of one function in some other functions.
The function return type is int& which says that you want to return a reference to an int variable.
If you want to access the array local array 'a' then the function should be rewritten as -
#include <iostream>
int* func();
int main()
{
int *arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
int *func()
{
int *a = new int[10];
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return a;
}
Alternatively you can also use vectors -
#include<iostream>
#include<vector>
std::vector<int>& func();
int main()
{
std::vector<int>& arrref = func();
std::cout<<arrref[1];//Error
std::cout<<&arrref[1];//Error
}
std::vector<int>& func()
{
std::vector<int> a(10);
for(int i = 0;i<10 ;++i)
a[i] = i*2;
return a;
}

C++ - fail to modify pointer in class member function

I defined a function getArray() in class A, like this:
void getArray(int * arr){
arr = new int[10];
arr[0] = 1;
}
I want to modify pointer arr in getArray(). And I invoked function getArray() in main(), like this:
int main(){
A obj;
int * arr = new int[2];
obj.getArray(arr);
cout<<arr[0]<<endl;
delete[] arr;
}
But when I executed main(), the output of arr[0] is 0, not 1. Why?
Actually, I want to allocate new memory to pointer arr and set the contents of the array in function getArray(). Then I want to get the contents of the array and deallocate pointer arr in main(). But I don't know what to do.
The array was not modified, because you reassign the variable in getArray. This code will work:
void getArray(int * arr){
arr[0] = 1;
}
You should decide where the memory for array is allocated. If the answer is in main, then you should deallocate it at the end of this function:
int main(){
A obj;
int * arr = new int[2];
obj.getArray(arr);
cout<<arr[0]<<endl;
delete[] arr;
}
If the array should be created in getArray, then you don't need the allocation in main, and you should return the new pointer from getArray, and don't forget to deallocate it:
int * getArray(){
int * arr = new int[10];
arr[0] = 1;
return arr;
}
int main(){
A obj;
int * arr = obj.getArray();
cout<<arr[0]<<endl;
delete[] arr;
}
Because you are calling getArray with a copy of your pointer.
You can call functions by-value or by-reference. Using a pointer may look like a by-reference call, yet it is a by-value call as a pointer only stores a reference.
You could use pass the pointer by-reference to achieve what you are trying to do: void getArray(int *& arr).
BTW: I hope that this code isn't somewhere in a productive environment as it has 2 memory leaks.
UPDATE:
Examples using std::vector:
Example 1:
#include<iostream>
#include<vector>
struct A
{
void getData(std::vector<int>& v){
v = std::vector<int>(10, 0); //vector with 10 zeros
v[0] = 1;
}
};
void printData(const std::vector<int>& v)
{
std::cout << "v.size() = " << v.size() << std::endl;
for(int value : v)
{
std::cout << value << std::endl;
}
}
int main(){
A obj;
std::vector<int> v;
obj.getData(v);
printData(v);
return 0;
}
Example 2:
#include<iostream>
#include<vector>
struct A
{
std::vector<int> getData(){
std::vector<int> v(10, 0); //vector with 10 zeros
v[0] = 1;
return v;
}
};
void printData(const std::vector<int>& v)
{
std::cout << "v.size() = " << v.size() << std::endl;
for(int value : v)
{
std::cout << value << std::endl;
}
}
int main(){
A obj;
std::vector<int> v = obj.getData();
printData(v);
return 0;
}

What interface will copy cstrings, arrays, and other types to instances of the same type?

Not all instances of a type can be copied to another instance of the same type with an = sign.
For example,
although it may work on ints:
int x = 0;
int y = 5;
x = y; //x is now: 5
It would not work on char arrays:
char x[32]="data to overwrite";
char y[32]="new data";
x = y; //incorrect
or other arrays:
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
x = y; //incorrect
or char*s:
char* x="data to overwrite";
char* y="new data";
x = y; //incorrect
How can I write an overloaded function that will allow me to do the following?
int x = 0;
int y = 5;
Copy(x,y); //x is now: 5
char x[32]="data to overwrite";
char y[32]="new data";
Copy(x,y); //x is now: "new data"
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
Copy(x,y); //x is now: {6,7,8,9,10}
char* x="data to overwrite";
char* y="new data";
Copy(x,y); //x is now: "new data"
*I'll assume that any abstract data types do the necessary work in their overloaded assignment operator(or from the shallow copy provided by the compiler)
Why do you need to do this?
In order to easier test portions of a legacy C code base, I'd like to generate some C++ wrappers around a few components. Due to the strange design of the C code, there is a lot of indirection that I would like to get rid of. As such, it would be a lot easier to copy variables into another instance using a simple Copy function instead of parsing out the types, and deciding how to make the appropriate copy into the other instance variable.
Here is a complete example, with couts sprinkled in to show that the correct overloads are selected.
#include <algorithm>
#include <cstddef>
#include <iostream>
#include <ostream>
// default
template<class T>
void Assign(T& dst, const T& src)
{
dst = src;
std::cout << "assign (default)" << std::endl;
}
// arrays
template<class T1, std::size_t n>
void Assign(T1 (&dst)[n], const T1 (&src)[n])
{
std::copy(src, src+n, dst);
std::cout << "assign (array)" << std::endl;
}
// pointers
template<class T1>
void Assign(T1 *&dst, T1 *src)
{
// DANGER: memory leaks/double frees
// not exactly sure what is supposed to happen here
// same as default for now...
// ok as long as only string constants are passed around
// (as is the case in the example)
dst = src;
std::cout << "assign (pointer)" << std::endl;
}
int main() {
{
int x = 0;
int y = 5;
Assign(x,y); //x is now: 5
}
{
char x[32]="data to overwrite";
char y[32]="new data";
Assign(x,y); //x is now: "new data"
}
{
int x[5] = {1,2,3,4,5};
int y[5] = {6,7,8,9,10};
Assign(x,y); //x is now: {6,7,8,9,10}
}
{
const char* x="data to overwrite";
const char* y="new data";
Assign(x,y); //x is now: "new data"
}
}
Output:
g++ -std=c++11 -g -Wall -O3 check.cc -o check && ./check
assign (default)
assign (array)
assign (array)
assign (pointer)
Here is my attempt on my own question:
#include <algorithm>
#include <cstring>
//catch all
template <typename T>
void Copy(T &x, T y)
{
x = y;
}
//overload on static array copying
//(T[N] = T[N])
template <typename T, size_t N>
void Copy(T(&x)[N], T(&y)[N])
{
std::copy(std::begin(y), std::end(y), std::begin(x));
}
//overload on copying of null terminated data
//(char array = cstring)
void Copy(char x[], const char y[])
{
//assumes x is >= to y
//not sure if I can use strncpy somewhow
strcpy(x, y);
}