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;
}
Related
I simplified the code, so pardon my style.
I was wondering what happens to an object that is constructed by a constructor that actually allocates memory, and passed to a lambda by value, when this lambda itself, is being a callback by another thread.
It didn't surprise me to see the program crashes when the destructor is called. This was test#1.
test#2: I removed the "new" and the "delete[]" from c'tor and d'tor of A, and now - it worked fine.
test#3:
I brought the "new" and the "delete[]" back as before, but now I changed every place with "A objA" (by value) into "A& objA", and now, it didn't crash as well.
Now, I can rationalize it by waving my hands but I'd like to understand what really happened here, and for that matter - what would happen if an object that is passed into a lambda by "capture", also ceases to exist.
and last question: is there a good practice or tip what to do (or what to avoid) in such cases?
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::chrono_literals;
class A {
public:
A() : x(1) { ptr = new char[1024]; }
~A() { delete[](ptr); }
int getX() { return x; }
private:
int x = 0;
char* ptr = nullptr;
};
std::function<void(A objA)> myCb;
int myThread()
{
static int counter = 0;
auto a = new A;
while (true) {
std::this_thread::sleep_for(2s);
if (myCb)
myCb(*a);
else
std::cout << "myCb is still NULL: counter = " << counter << std::endl;
if (counter++ == 5)
break;
}
return 0;
}
void registerCallback(std::function<void(A obj)> cb)
{
myCb = cb;
}
int main()
{
std::thread t1(myThread);
std::this_thread::sleep_for(6s);
int val = 5;
registerCallback([&val](A objA) {
std::cout << "here lambda is called with " << objA.getX() << " and " << val << std::endl;
});
val = 6;
std::this_thread::sleep_for(1s);
val = 7;
std::this_thread::sleep_for(1s);
val = 8;
std::this_thread::sleep_for(1s);
t1.join();
}
class A is violating the Rule of 3/5/0, as it does not implement a copy-constructor and/or move-constructor, or a copy-assignment and/or move-assignment operator.
So, when an instance of A is passed around by value, a shallow copy is made that shares the same char* pointer to a single char[] array in memory, and thus the code MAY crash (ie, undefined behavior) when trying to delete[] that same array multiple times.
What you need is a deep copy instead, so that each instance of A allocates its own char[] array, eg:
class A
{
public:
A() : x(1), ptr(new char[1024])
{
std::fill(ptr, ptr + 1024, '\0');
}
A(const A &src) : x(src.x), ptr(new char[1024])
{
std::copy(src.ptr, src.ptr + 1024, ptr);
}
A(A &&src)
: x(src.x), ptr(src.ptr)
{
src.ptr = nullptr;
}
~A()
{
delete[] ptr;
}
A& operator=(A rhs)
{
std::swap(x, rhs.x);
std::swap(ptr, rhs.ptr);
return *this;
}
int getX() const { return x; }
private:
int x;
char* ptr;
};
A simpler way to implement this is to use std::vector instead of new[], since vector is already compliant with the Rule of 3/5/0, and so compiler-generated constructors, destructor, and assignment operators for A will suffice to make copies/moves of the vector for you, eg:
#include <vector>
class A
{
public:
A() : vec(1024, '\0') {}
int getX() const { return x; }
private:
int x = 1;
std::vector<char> vec;
};
You should use unique_ptr. deleting a void* is undefined behavior
#include <iostream>
#include <thread>
#include <future>
#include <chrono>
using namespace std::chrono_literals;
class A {
public:
A() : x(1)
{
ptr = std::make_unique<char[]>(1024);
}
~A()
{
}
int getX() { return x; }
private:
int x = 0;
std::unique_ptr<char[]> ptr = nullptr;
};
std::function<void(A& objA)> myCb;
int myThread()
{
static int counter = 0;
auto a = new A;
while (true) {
std::this_thread::sleep_for(2s);
if (myCb)
myCb(*a);
else
std::cout << "myCb is still NULL: counter = " << counter << std::endl;
if (counter++ == 5)
break;
}
return 0;
}
void registerCallback(std::function<void(A& obj)> cb)
{
myCb = cb;
}
int mymain()
{
std::thread t1(myThread);
std::this_thread::sleep_for(6s);
int val = 5;
registerCallback([&val](A& objA) {
std::cout << "here lambda is called with " << objA.getX() << " and " << val << std::endl;
});
val = 6;
std::this_thread::sleep_for(1s);
val = 7;
std::this_thread::sleep_for(1s);
val = 8;
std::this_thread::sleep_for(1s);
t1.join();
return 0;
}
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];
I'm using C++ and am trying to set an array element values with a setter method. The array is a class private member:
class Boo{
private:
int *x;
public:
Boo();
~Boo();
void setX(int,int);
int getX(int);
}
Boo::Boo(){
x = new int[1];
x = 0;
}
void Boo::setX(int value, int index){
//set condition for NULL
x[index] = value;
}
int Boo::getX(int index){
if(x[index] == NULL) {cout<<"invalid index"<<end; return;}
return x[index];
}
void test(){
Boo *p = new Boo();
p->setX(12,0);
cout<<p->getX(0)<<endl;
}
I been trying to test setting the values in 'x' starting with index '0' (like test()) but it crashes. I wanted to write a program where I run a loop counting up, and I set the array values. Can this be accomplish this way?
Do not use new in C++!
In this case, you should use std::vector<int>.
If you want to fix your code unless use std::vector,
#include <cstddef>
#include <iostream>
#include <stdexcept>
#include <memory>
using std::size_t;
class Boo {
private:
int *x;
size_t size;
size_t capacity;
public:
Boo();
~Boo();
void setX(int,size_t);
int getX(size_t);
};
Boo::Boo() : size(), capacity(1) {
this->x = new int[1];
//x = 0;//DO NOT ASSIGN NULL POINTER!!!!
}
Boo::~Boo() noexcept {
delete[] x;
}
void Boo::setX(int value, size_t index){
if(this->capacity <= index) throw std::out_of_range("Boo::setX");//YOU MUST CHECK RANGE
this->x[index] = value;
++this->size;
}
int Boo::getX(size_t index){
if(this->size <= index) throw std::out_of_range("Boo::getX");//YOU MUST CHECK RANGE
return x[index];
}
void test(){
auto p = std::make_unique<Boo>();
p->setX(12,0);
std::cout << p->getX(0) << std::endl;
}
int main(){
test();
}
http://melpon.org/wandbox/permlink/aIhwC5c9o1q8ygIo
Boo::Boo()
{
x = new int[1];
x = 0;
}
you are not able to set value in an array because after initializing with memory, you have set the pointer of an array to null in constructor.
please use x[0] = 0; instead of x = 0;
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;
}
I'm trying to dust off my C++. I knocked together a simple program to find the Fibonacci sequence with memoization. There's a memory leak, and I can't seem to figure out why. The leak is reported in Fibonacci::setToFind.
Sorry for the long code chunk, but I couldn't figure out how to make a more minimal reproducible example.
#include <iostream>
class Fibonacci
{
public:
int m_valuefound;
int m_tofind;
long int *m_memo;
int findValue(int value){
if (m_memo[value] == 0) {
if (value == 0 || value == 1) {
m_memo[value] = 1;
} else {
m_memo[value] = findValue(value-1) + findValue(value-2);
}
}
return m_memo[value];
}
void setToFind(int value){
m_tofind = value;
m_memo = new long int[value];
std::fill_n(m_memo,value,0);
}
void solve(){
int value = m_tofind;
int result = findValue(value);
std::cout<< "Value is: " << result << std::endl;
}
~Fibonacci(){};
};
int main (int argc, char * const argv[]) {
std::cout << "Enter integer values until you'd like to quit. Enter 0 to quit:";
int user_ind=0;
// for testing non-interactivly
while(true){
for (user_ind=1; user_ind<45; user_ind++) {
Fibonacci *test = new Fibonacci;
test->setToFind(user_ind);
test->solve();
delete test;
}
}
return 0;
}
You never delete m_memo in the destructor of Fibonacci.
Since you're allocating m_memo as an array, you should delete with delete[] m_memo
Here is working code with a non-copyable Fibonacci class. Why don't
you allocate the memory in the constructor. Use RAII wherever possible
and remember The Rule of Five. Avoid all of this in the first place by
using std::vector.
#include <iostream>
class Fibonacci
{
public:
int m_valuefound;
int m_tofind;
long int *m_memo;
int findValue(int value){
if (m_memo[value] == 0) {
if (value == 0 || value == 1) {
m_memo[value] = 1;
} else {
m_memo[value] = findValue(value-1) + findValue(value-2);
}
}
return m_memo[value];
}
void setToFind(int value){
m_tofind = value;
m_memo = new long int[value];
std::fill_n(m_memo,value,0);
}
void solve(){
int value = m_tofind;
int result = findValue(value);
std::cout<< "Value is: " << result << std::endl;
}
// why don't you allocate in the constructor?
Fibonacci() : m_valuefound(0), m_tofind(0), m_memo(nullptr) {}
~Fibonacci() {
delete[] m_memo;
};
// make the class non-copyable
Fibonacci(const Fibonacci&) = delete;
const Fibonacci& operator=(const Fibonacci&) = delete;
/*
C++03 non-copyable emulation
private:
Fibonacci(const Fibonacci&);
const Fibonacci& operator=(const Fibonacci&);
*/
};
You are allocating m_memo in setToFind:
m_memo = new long int[value];
but your destructor does not have a delete [] m_memo. You should initialize m_memo in your constructor and make you class non-copyable by disabling your copy constructor and assignment operator using delete if using C++11:
Fibonacci(const Fibonacci&) = delete;
const Fibonacci& operator=(const Fibonacci&) = delete;
Otherwise you can make them private. If you used a container such as std::vector your life would be much simpler.
I suggest you use more the STL algorithms. Here's a code snippet with a rather not optimized functor but you can get the idea of the power of the STL:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
class Fibonacci
{
public:
Fibonacci();
~Fibonacci() {}
int operator()();
private:
int n0_;
int n1_;
int n_;
};
Fibonacci::Fibonacci():n0_(0),n1_(1),n_(0)
{
}
int Fibonacci::operator()()
{
if(n_ > 1)
return (++n0_) + (++n1_);
else
return ++n_;
}
using namespace std;
int main()
{
Fibonacci func;
vector<int> v;
//generate 100 elements
generate_n(v.begin(),100,func);
//printing the values using a lambda expression
for_each(v.begin(),v.end(),[](const int val){cout << val << endl;});
return 0;
}
You can then apply the finding algorithm you want on the vector using find_if and defining your own functor.