#include"iostream"
class CMessage
{
public:int a;
CMessage(){}
~CMessage(){}
};
void Testing(CMessage *f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
int main()
{
CMessage *l_pMessage =NULL;
Testing(l_pMessage);
std::cout<<l_pMessage->a;//getting l_pMessage = NULL;
return 0;
}
When I called testing then inside testing f_pMessage is getting initialized but as soon as
i after excuting testing function it should be store in l_Pmessage but it is showing NULL.confussed.....
Testing(l_pMessage);
At this line, you are passing a copy of the pointer. You either need to pass a pointer to pointer or a reference to pointer:
void Testing(CMessage *& f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
You can do it the other way using a pointer to pointer:
void Testing(CMessage **f_pMessage)//l_pMessage is output parameter
{
*f_pMessage = new CMessage();
(*f_pMessage)->a = 1;
}
But you have to call the function this way:
Testing(&l_pMessage);
Passing by pointer only allows you to modify what is being pointed at. The pointer itself is still being passed by value.
Since you want to change a pointer, you can either pass a pointer to a pointer or take the pointer by reference:
void Testing(CMessage *&f_pMessage)//l_pMessage is output parameter
{
f_pMessage = new CMessage();
f_pMessage->a = 1;
}
The pointer itself is copied by value.
f_pMessage = new CMessage();
modifies the pointer itself, not the object it points to. Try:
void Testing(CMessage *f_pMessage)
{
f_pMessage->a = 1;
}
int main()
{
CMessage *l_pMessage = new CMessage();
Testing(l_pMessage);
std::cout<<l_pMessage->a;
return 0;
}
Or, if you want to create the object in your function:
CMessage *Testing()
{
CMessage *f_pMessage = new CMessage();
f_pMessage->a = 1;
return f_pMessage;
}
int main()
{
CMessage *l_pMessage = Testing();
std::cout<<l_pMessage->a;
return 0;
}
A pointer to a pointer is the way to go or a pointer reference
void testA(int** var)
{
*var = new int;
**var = 3;
}
void testB(int*& var)
{
var = new int;
*var = 3;
}
Use like this:
// Method a
int* a;
testA(&a);
std::cout << "a: " << *a << "\n";
// Method b
int* b;
testB(b);
std::cout << "b: " << *b << "\n";
// Dont forget to delete!
delete a;
delete b;
I hope this explains it.
The answers I have seen are correct, but they have omitted the most important point I think: you should not use a raw pointer, because you don't have any ownership semantics here.
void Testing(std::unique_ptr<CMessage>& message)
{
message = std::unique_ptr<CMessage>(new CMessage());
message->a = 1;
}
int main(int argc, char* argv[])
{
std::unique_ptr<CMessage> l_pMessage;
Testing(l_pMessage);
std::cout << l_pMessage->a;
return 0;
}
This is better because it uses proper semantics to indicate within the code who is responsible for the allocated object, and use the type system to have the compiler enforce correct use.
Now, I would advise another interface:
std::unique_ptr<CMessage> Testing()
{
return std::unique_ptr<CMessage>(new CMessage(1));
}
int main(int argc, char* argv[])
{
std::unique_ptr<CMessage> l_pMessage = Testing();
std::cout << l_pMessage->a;
return 0;
}
Related
Question might be a bit confusing; here's the problem:
I have this:
class FunctionContainer
{
void* functionPointer;
}
void Test()
{
cout << 'a';
}
int main()
{
FunctionContainer* f = new FunctionContainer();
f->functionPointer = &Test;
f->functionPointer;
}
My problem here is that I can't invoke the function like this, it just skips the line. What am I doing wrong here?
The correct way is this:
class FunctionContainer
{
public:
void (*functionPointer)(void);
}
void Test()
{
cout << 'a';
}
int main()
{
FunctionContainer* f = new FunctionContainer();
f->functionPointer = &Test;
f->functionPointer();
}
Where
returnType (*variableName)(argumentType1, argumentType2, argumentType3...);
And (in this example)
returnType name = f->variableName(argument1, argument2, argument3...);
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define ROW 1
class Foo
{
public:
Foo()
{
this->dummy = new unsigned int[100];
}
~Foo()
{
delete[] this->dummy;
this->dummy = NULL;
}
unsigned int* dummy;
};
Foo** allocate()
{
Foo** foo_array = NULL;
foo_array = new Foo * [ROW]; //Create space for Foo addresses (row)
for (int i = 0; i < ROW; i++)
foo_array[i] = new Foo; //Create and allocate Foo for each address space(col)
return foo_array;
}
int deallocate(Foo* foo_array[ROW])
{
if (foo_array != NULL)
{
for (int i = 0; i < ROW; i++)
delete foo_array[i];
delete[] foo_array;
foo_array = NULL;
return 1;
}
return 0;
}
void main()
{
Foo** foo_array = NULL;
foo_array = allocate();
deallocate(foo_array);
if (foo_array != NULL)
printf("not null something wrong\n");
system("pause");
}
In main() function, foo_array should be pointed to NULL as soon as the deallocation is performed by the deallocate(Foo* foo_array[ROW]) function.
but, In deallocate(Foo* foo_array[ROW]) function,
foo_array = NULL;
It seems point to NULL by above syntax, however in main() function,
foo_array is not point to NULL.
so, I tried to change above syntax in deallocate(Foo* foo_array[ROW]) function,
foo_array = NULL; => (*foo_array) = NULL;
It spits out write access violation errors.
Where did it go wrong?
I don't see any reason to declare foo_array as pointer to pointer. In your code you are passing pointers by value. That means you can change what the pointers are pointing at but you can't change the values of the pointers. You can solve the problem using references.
#include <cstdio>
#define ROW 1
class Foo
{
public:
Foo()
{
this->dummy = new unsigned int[100];
}
~Foo()
{
delete[] this->dummy;
this->dummy = NULL;
}
unsigned int *dummy;
};
void allocate(Foo *&foo_array)
{
foo_array = new Foo[ROW];
}
void deallocate(Foo *&foo_array)
{
delete[] foo_array;
foo_array = nullptr;
}
int main()
{
Foo *foo_array = nullptr;
allocate(foo_array);
deallocate(foo_array);
if (foo_array != nullptr)
printf("not null something wrong\n");
}
Of course you can make your code much simpler using STL containers or smart pointers
The correct syntax would be foo_array = deallocate (foo_array); and your deallocate should return NULL.
This question already has answers here:
Do Pointer Parameters Need To Be Passed By Reference
(3 answers)
Closed 3 years ago.
Object made using new operator does not seem to be available outside the scope! Isn't that the whole point of the new operator?
https://ideone.com/DDvo9y - Please check this link to see the result.
#include<iostream>
class myClass
{
private:
int val;
public:
myClass () = delete;
myClass (int val):val{val}{}
int get () const
{
return val;
}
};
bool ifEqualMake (int a, int b, myClass * obj)
{
if (a == b) obj = new myClass (a);
else{
std::cout << "Difference exists: " << a - b << '\n';
obj = new myClass (a + b);
}
std::cout << " Object made with value :" << obj->get () << '\n';
return (a == b);
}
int main ()
{
myClass *obj1 = nullptr;
myClass *obj2 = nullptr;
myClass *obj3 = nullptr;
ifEqualMake (3, 3, obj1);
ifEqualMake (4, 3, obj2);
ifEqualMake (4, 4, obj3);
if(obj1) std::cout << "obj 1 made in heap: " << obj1->get () << '\n';
if(obj2) std::cout << "obj 2 made in heap: " << obj2->get()<<'\n';
if(obj3) std::cout << "obj 3 made in heap: " << obj3->get () << '\n';
delete obj1;
delete obj2;
delete obj3;
return 0;
}
It isn't.
You're confusing the dynamically-allocated object that you created with new, and the pointer that points to it.
The pointer's scope is limited just like any other automatic-storage-duration object.
It looks like you meant to use it as an "out" argument to the function ifEqualMake, perhaps by taking a reference to it rather than a copy. Then alterations to it, such as pointing it to a new object, will be mirrored in the calling scope.
The parameter obj is passed by value, that means it's just a copy of the argument, and any modification on itself inside the function (like obj = new myClass (a);) has nothing to do with the original pointer. In the meanwhile, the object constructed inside the function won't be destroyed.
You might change it to pass-by-reference.
bool
ifEqualMake (int a, int b, myClass *& obj)
// ^
{
...
}
Consider the following function:
void foo(int i) {
i = 4;
}
void bar() {
int j = 0;
foo(j);
std::cout << j << '\n';
}
You would expect bar to print 0, not 4, because foo is assigning to a local variable.
This behaviour does not change with pointers. The following code behaves the same way:
void foo(int* i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
std::cout << j << '\n';
}
The simplest fix to the code you present is to take the pointer by reference:
void foo(int*& i) {
int temp = 0;
i = &temp;
}
void bar() {
int* j = nullptr;
foo(j);
// j now points to a destroyed object
std::cout << j << '\n';
}
I have a struct containing dynamic struct arrays:
struct C_Node {
int id;
int num_children;
int* children;
};
struct C_Transition {
int id;
int duration;
int num_parents;
int num_children;
int* parents;
int* children;
};
struct C_PetriNet {
int num_nodes;
int num_transitions;
C_Node* nodes;
C_Transition* transitions;
};
I want to initialize and return the outer struct like the following:
C_PetriNet* Cpp_C_interface::convert_PetriNet(PetriNet petriNet) {
int num_nodes = static_cast<int>(petriNet.nodes.size());
int num_transitions = static_cast<int>(petriNet.transitions.size());
C_PetriNet* c_petriNet = (C_PetriNet*)malloc(sizeof(C_PetriNet));
C_Node* c_nodes = new C_Node[num_nodes];
C_Transition* c_transitions = new C_Transition[num_transitions];
for (int i = 0; i < num_nodes; i++) {
c_nodes[i].id = petriNet.nodes[i].id;
c_nodes[i].num_children = petriNet.nodes[i].childs.size();
c_nodes[i].children = petriNet.nodes[i].childs.data();
}
for (int i = 0; i < num_transitions; i++) {
c_transitions[i].id = petriNet.transitions[i].id;
c_transitions[i].duration = petriNet.transitions[i].duration;
c_transitions[i].num_parents = petriNet.transitions[i].parents.size();
c_transitions[i].num_children = petriNet.transitions[i].childs.size();
c_transitions[i].children = petriNet.transitions[i].childs.data();
c_transitions[i].parents = petriNet.transitions[i].parents.data();
}
c_petriNet->num_nodes = num_nodes;
c_petriNet->num_transitions = num_transitions;
c_petriNet->nodes = c_nodes;
c_petriNet->transitions = c_transitions;
return c_petriNet;
};
And use it in the main:
C_PetriNet* c_petriNet;
c_petriNet = Cpp_C_interface::convert_PetriNet(petriNet);
std::cout << "Test out: " << c_petriNet->num_nodes << std::endl;
std::cout << "Test out: " << c_petriNet->nodes[5].children[8] << std::endl;
std::cout << "Test out: " << c_petriNet->transitions[68].parents[1] << std::endl;
However, only the first output (num_nodes) is correct. If I print inside the function before returning, everything works fine. What can I do to return also the dynamic allocated memory?
The problem is that petriNet is a local copy of the object that was passed to your function. You're saving pointers to the data() of various vectors in petriNet in the new C_Node and C_Transition that you're creating, but these pointers become invalid when the function returns.
If you change your function to take a reference, the pointers will remain valid as long as the caller's object is alive, but that's still fragile. What you really need to do is make copies of all the data. So you can use memcpy():
memcpy(c_nodes[i].children, petriNet.nodes[i].childs.data(), c_nodes[i].num_children * sizeof(*petriNet.nodes[i].childs.data());
my type aButton has a function pointer so i can define custom actions for each button, i though the easiest way to do this would be to create a lambda and dereference it and pass it to the function pointer of that aButton instance, since i need non-static access to objects outside of the scope of the button class
but i'm stuck trying to figure out how to cast it to the right type and how to call it without getting the errors below... i haven't see many people have luck with this, and using functional doesn't look like i can pass in context???
// Example program
#include <iostream>
#include <string>
int global1 = 0;
int global2 = 5;
class aButton {
public:
int status, oldStatus;
aButton(int initStatus) { oldStatus = status = initStatus; }
int (aButton::*action)();
};
class Thingy {
private:
int mode = 1;
int value = 0;
public:
void reset() { value = 0; }
void setMode(int newMode) { mode = newMode; }
void increment() { value = value + global2; }
//accessors & mutators
};
void specialFunction(Thingy *thingyToWorkOn) {
//do stuff...
}
void anotherSpecialFunction(Thingy *firstThingy, Thingy *secondThingy) {
//more stuff...
}
int main() {
Thingy one;
Thingy two;
aButton *on = new aButton(0);
aButton *speedUp = new aButton(0);
on->action = &( //error: taking address of temporary [-fpermissive]
[&]() { //error: cannot convert 'main()::<lambda()>*' to 'int (aButton::*)()' in assignment
//some specific stuff....
global1 = 1;
if (global2 < 10) {
global2++;
}
one.reset();
two.reset();
anotherSpecialFunction(&one, &two);
std::cout << "on action \n";
return 1;
}
);
speedUp->action = &( //error: taking address of temporary [-fpermissive]
[&]() { //error: cannot convert 'main()::<lambda()>*' to 'int (aButton::*)()' in assignment
//some specific stuff....
if (global1) {
one.setMode(global2);
two.setMode(global2);
specialFunction(&one);
specialFunction(&two);
std::cout << "speedUp action \n";
return 1;
}
return 0;
}
);
for(int i=0; i<5; i++) {
//if on pushed
(on->(on->action))(); //error: expected unqualified-id before '(
//if speedUp pushed
(speedUp->(speedUp->action))(); //error: expected unqualified-id before '(
}
}
I believe that you want aButton::action to be of type std::function<int()> (read: function that takes nothing and returns int) rather than int (aButton::*). This requires the <functional> header. With that change, your assignments could stay the same (minus the leading address-of operator), though as you figured out, you'll need to explicitly state the return type with -> int. The calls would simply take the form (e.g.):
on->action();
One other note: be very careful about capturing local variables (one, two) by reference. If the function really is main then I suppose it's ok since main won't return until the program ends, but otherwise it would be asking for trouble.
You cannot assign pointer to lambda to pointer to member function. Pointers to member functions may point only to member functions.
You can indeed use std::function from <functional> instead. Declare your action as
std::function<int()> action;
so instead of using member functions you will use global functions. Of course you need to get rid of & operators for lambdas. And you need to modify the way of calling action.
Thanks guys, i guess functional was what i was looking for after all... this seems to do what i want on http://cpp.sh/8ll i guess i just got confused cause a lot of the functional examples had them as arguments for callbacks instead
// Example program
#include <iostream>
#include <string>
#include <functional>
int global1 = 0;
int global2 = 5;
class aButton {
public:
int status, oldStatus;
aButton(int initStatus) { oldStatus = status = initStatus; }
std::function<int()> action;
};
class Thingy {
private:
int mode = 1;
int value = 0;
public:
void reset() { value = 0; }
void setMode(int newMode) { mode = newMode; }
void increment() { value = value + global2; }
//...
};
void specialFunction(Thingy *thingyToWorkOn) {
//do stuff...
}
void anotherSpecialFunction(Thingy *firstThingy, Thingy *secondThingy) {
//more stuff...
}
int main() {
Thingy one;
Thingy two;
aButton *on = new aButton(0);
aButton *speedUp = new aButton(0);
on->action = std::function<int()>(
[&]() -> int{
//some specific stuff....
global1 = 1;
if (global2 < 10) {
global2++;
}
one.reset();
two.reset();
anotherSpecialFunction(&one, &two);
std::cout << "on action \n";
return 1;
}
);
speedUp->action = std::function<int()>(
[&]() -> int{
//some specific stuff....
if (global1) {
one.setMode(global2);
two.setMode(global2);
specialFunction(&one);
specialFunction(&two);
std::cout << "speedUp action \n";
return 1;
}
return 0;
}
);
for(int i=0; i<5; i++) {
//if on pushed
on->action();
//if speedUp pushed
speedUp->action();
}
}