C/C++ Vector and reference parameter - c++

I want to receive a VECTOR in my main function. The code is this.
int myfunction(void);
int main(){
int p = myfunction(void);
std::cout << p[2] << std::endl;
};
int myfunction(void){
int new array[4]={0,1111,2222,3333};
int *p;
p = array;
return p;
};

In C++ you would do:
std::vector<int> myfunction();
int main(){
std::vector<int> p = myfunction();
std::cout << p[2] << std::endl;
}
std::vector<int> myfunction(){
return std::vector<int>{0,1111,2222,3333};
}
And in C you could do:
int* myfunction(void);
int main(void){
int* p = myfunction();
printf("%d\n", p[2]);
free(p);
}
int* myfunction(void){
int tmp[] = {0,1111,2222,3333};
int* array = (int*)malloc(sizeof(tmp));
memcpy(array, &tmp, sizeof(tmp));
return array;
}
Now if you have trouble with this code, I'd recommend you go pick a good C or C++ book (whichever it is you're interested in) and read up on the basics of the language, because you seem really confused.

Related

Problem with allocating memory in function [duplicate]

This question already has answers here:
pass by reference and value with pointers [duplicate]
(5 answers)
Closed 3 years ago.
I am not a beginner in C/C++ but I can't seem to find what is wrong with this piece of c++ code. I also tried it with the c equivalent(malloc) and I get the same result.
#include <iostream>
void foo(int *n) {
n = new int;
*n = 11;
}
int main() {
int *num = NULL;
foo(num);
std::cout << num << '\n';
if (num) {
delete num;
}
return 0;
}
n is a pointer that is being passed by value, so any modifications made by the function to the pointer itself are not applied to the caller's variable. And as such, you are leaking memory since you are new'ing memory that you are not able to delete afterwards.
To do what you are attempting, you need to pass n by reference instead:
void foo(int* &n) {
n = new int;
*n = 11;
// or simply:
// n = new int(11);
}
Otherwise, you should change your function to return the new pointer instead of outputting it via a reference parameter:
#include <iostream>
int* foo() {
int *n = new int;
*n = 11;
return n;
// or simply:
// return new int(11);
}
int main() {
int *num = foo();
std::cout << num << '\n';
delete num;
return 0;
}
That being said, in C++11 and later, you should be using std::unique_ptr instead of a raw pointer:
#include <iostream>
#include <memory>
void foo(std::unique_ptr<int> &n) {
n.reset(new int(11));
// or:
// std::unique_ptr<int>(new int(11)).swap(n);
// or, in C++14 and later:
// n = std::make_unique<int>(11);
}
int main() {
std::unique_ptr<int> num;
foo(num);
std::cout << num.get() << '\n';
return 0;
}
#include <iostream>
#include <memory>
std::unique_ptr<int> foo() {
return std::unique_ptr<int>(new int(11));
// or, in C++14 and later...
// return std::make_unique<int>(11);
}
int main() {
std::unique_ptr<int> num = foo();
std::cout << num.get() << '\n';
return 0;
}

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;
}

Const pointers shallow copy

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