I'm using Qt Creator 4.5 with GCC 4.3 and I'm having the following problem that I am not sure is Qt or C++ related: I call a function with a char * as an input parameter. Inside that function I make a dynamic allocation and I assign the address to the char *. The problem is when the function returns it does not point to this address anymore.
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
msgByte=new char[theSize];
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
When I return the pointer it contains a completely different address than the one assigned in putDatagrams(). Why?
...
Ok thx I understand my mistake(rookie mistake :( ). When sending a pointer as an input parameter to the function you send the address of your data but not the address of your pointer so you cant make the pointer point somewhere else...it is actually a local copy like Index. The only case the data would of been returned succesfully with the use of a char * is by allocating the memory before the function call:
bool FPSengine::putData (char CommandByte , int Index)
{
char *msgByte;
msgByte=new char[sizeof(MsnConfigType)];
structSize=putDatagrams(CommandByte, Index, msgByte);
}
int FPSengine::putDatagrams (char CommandByte, int Index, char *msgByte)
{
int theSize;
switch ( CommandByte ) {
case (CHANGE_CONFIGURATION): {
theSize=sizeof(MsnConfigType);
union MConfigUnion {
char cByte[sizeof(MsnConfigType)];
MsnConfigType m;
};
MConfigUnion * msnConfig=(MConfigUnion*)msgByte;
...Do some assignments. I verify and everything is OK.
}
}
return theSize;
}
There are two ways. The pass-by-value way (C style):
int FPSengine::putDatagrams (char CommandByte, int Index, char **msgByte)
Note the second * for msgByte. Then inside of putDatagrams(), do:
*msgByte = new char[theSize];
In fact, anywhere in that function where you currently have msgByte, use *msgByte. When calling putDatagrams(), do:
structSize=putDatagrams(CommandByte, Index, &msgByte);
And the second way, since you're in C++, you could use pass-by-reference. Just change the signature of putDatagrams() to:
int FPSengine::putDatagrams (char CommandByte, int Index, char * &msgByte)
And you should be good. In this case, you shouldn't need to modify the caller or anything inside of your putDatagrams() routine.
Well, yes. Everything in C++ is, by default, passed by value. Parameters in the call putDatagrams(a, b, c) are sent by value - you wouldn't expect assigning to index in the code to change the value of b at the call site. Your msgByte=new char[theSize]; is just assigning to the local variable msgByte, overwriting the value passed in.
If you want to change a passed parameter such that the call site variable changes, you'll need to either pass by reference, or (in this case) pass a "pointer to a pointer` (and deference away the first pointer, assigning to the actual pointer).
Related
In C we should return pointer variable if define as 1- static stack 2- Heap-allocated 3-const address.
The question is:
Can argv** variable in main function be returned as a function return value without undefined behaviour?
I can't imagine a situation which requires to return argv** from a function, but you get it from main (int argc, char* argv[]) so yes. You can pass it as a parameter to a function and return it to another function. They're like const for you.
You can't return pointer to the data allocated temporarily for the function's own needs. int* F{ int A; return &A; } will not work. But you can set int* A=(int*)malloc(sizeof(int)); and return A;: it'll be your tiny wrapper around the malloc function. You can even receive int* A as a parameter and return A+1; the rule you mentioned in the beginning actually means "there are some restrictions of allocation methods if you're planning to use the pointer after the function exits". You can break the rule without returning the value (for example, you can store the poiner in a global variable and it'll become invalid when the function exits, like void F{ int A; GlobPtr=&A; } which will cause the same problems).
But your function does not allocate argv, it's allocated before your code starts. So you can even shift it by one value as you extract parameters one-by-one, the returned pointer *nextargv[] will also point to valid memory area.
How they have use the pointers in the function compare.
I could not understand.
Can somebody explain me this.
Function:-
int compare (const void *a, const void * b)
{
return ( (*(Box *)b).d * (*(Box *)b).w ) -
( (*(Box *)a).d * (*(Box *)a).w );
}
Link: https://www.geeksforgeeks.org/box-stacking-problem-dp-22/
(Box *)b it's a casting type from void to Box struct.
(*(Box *)b).d it's a dereferencing from Box struct's pointer. So, you can handle the structure as an instance, and then get struct's fields values as b.d.
Another option could be to use the pointer and avoid dereferencing with: b->d.
At the end, the compare function does: (dw) - (dw)'. If result were 0, then compare indicates both structures has same values.
PD. At (2): don't forget you are receiving the parameter as a pointer, and this implementation dereferences it as (*b).d
I am currently struggling with creating a Frama-C-plugin that gets all int-values of structs in a hierarchy (structs in structs).
For example:
I have a C-Program with the following types:
struct a{
int a;
int b;
}
struct b{
int c;
int d;
struct a a1;
struct a a2;
}
(And even deepter hierarchie)
In the program, there is only one struct of type b created in the main method. Furthermore, I have several local pointers and ints (so a solution only for a struct-hierarchy doesn't help).
Now I want to get the "bottom-values" of the struct of type b at some specific positions.
I've started with code like this:
let lval =
if (Cil.isPointerType vi.vtype) then (
(Mem (Cil.evar vi), NoOffset)
) else if (Cil.isStructOrUnionType vi.vtype)(
(*TODO Section*)
) else (
(Var vi, NoOffset)
)
int* and int's are already working fine, I use the lval-variable to get the value.
To get the struct's values, I think I have to go down vi recursivly, until I get to the point where it is a "normal" variable or a pointer, but how do I do this?
I've already looked at varinfo in cil_types.mli, but I have no idea how to get the data in the struct.
Is it even possible to get the result of the value-analysis for these values, and if yes, how?
For single linklist
1.1. This is what I saw from a tutorial, I only wrote the important part.
sortedInsert(Node **root, int key){};
int main(){
Node *root = &a;
sortedInsert(&root, 4);
}
1.2. However I just used pointer rather than double pointer, and everything works fine, I can insert the key successfully.
sortedInsert(Node *root, int key){};
int main(){
Node *root = &a;
sortedInsert(root, 4);
}
For binary Tree
2.1. From tutorial(double pointer)
void insert_Tree(Tree **root, int key){
}
int main(){
Tree *root = NULL;
insert_Tree(&root, 10);
}
2.2. what I did is below, and I failed to insert the key, when I checked the node after insertion, the node is still null.(single pointer)
void insert_Tree(Tree *root, int key){
if(root == NULL){
root = (Tree *)malloc(sizeof(Tree));
root->val = key;
root->left = NULL;
root->right = NULL;
cout<<"insert data "<<key<<endl;
}else if(key< root->val){
insert_Tree(root->left, key);
cout<<"go left"<<endl;
}else{
insert_Tree(root->right, key);
cout<<"go right"<<endl;
}
}
int main(){
Tree *root = NULL;
insert_Tree(root, 10);
}
I have a few questions
1). which is right, 1.1/2.1 double pointer or 1.2/2.2 single pointer? Please explain in detail, it could be better if you can show an example, I think both of them are right.
2). Why did I insert key successfully in the linkedlist with single pointer, however I failed in the tree insertion with single pointer?
Thanks very much, I appreciate everyone's help.
I suspect you were lucky with your linked list test. Try inserting something at the head of the list.
To expand on that...
main() has a pointer to the head of the list which it passes by value into your version of sortedInsert(). If sortedInsert() inserts into the middle or end of the list then no problem, the head is not changed and when it returns to main() the head is the same. However, if your version of sortedInsert() has to insert a new head, fine it can do that, but how does it return the information about the new head back to main()? It can't, when it returns to main() main will still be pointing at the old head.
Passing a pointer to main()'s copy of the head pointer allows sortedInsert() to change its value if it has to.
both your approaches are correct.But where you used a single pointer ,your head pointer isn't being updated.All you need to do is return the new head by writing 'return head;' at the end of your function,
I've got the following struct:
struct Param
{
double** K_RP;
};
And I wanna perform the following operations on "K_RP" in CUDA
__global__ void Test( struct Param prop)
{
int ix = threadIdx.x;
int iy = threadIdx.y;
prop.K_RP[ix][iy]=2.0;
}
If "prop" has the following form, how should I do my "cudaMalloc" and "cudaMemcpy" operations?
int main( )
{
Param prop;
Param cuda_prop;
prop.K_RP=alloc2D(Imax,Jmax);
//cudaMalloc cuda_prop ?
//cudaMemcpyH2D prop to cuda_prop ?
Test<<< (1,1), (Imax,Jmax)>>> ( cuda_prop);
//cudaMemcpyD2H cuda_prop to prop ?
return (0);
}
Questions like this get asked from time to time. If you search on the cuda tag, you'll find a variety of examples with answers. Here's one example.
In general, dynamically allocated data contained within structures or other objects requires special handling. This question/answer explains why and how to do it for the single pointer (*) case.
Handling double pointers (**) is difficult enough that most people would recommend "flattening" the storage so that it can be handled by reference with a single pointer (*). If you really want to see how the double pointer (**) method works, review this question/answer. It's not trivial.