How to print a C structure recursively in gdb - gdb

How can I make gdb print a structure's fields recursively,
i.e. follow pointers.
Right now, I have to go inside each field and either specify a '*' to print
the sub structure, or have to type cast to see what's inside the substructure.
e.g.
typedef struct {
int a;
}A;
typedef struct {
A *pA;
int b;
}B;
typedef struct {
B *pB;
int c;
}C;
C var_c;
C *pC = var_c;
...
...
Now, I would like to do "p *pc" on gdb prompt,
to see everything rather than just the address of pB.

The best way to achieve what you want is to write a python pretty-printer for your structs. Documentation here.

Related

coder.ceval struct requires pointer

I am using some external C++ code from within Matlab by calling it via coder.ceval:
coder.ceval('myCppFuncName', coder.wref(mySruct))
This works perfectly as long as myStruct is something simple as
myStruct.a = 0;
myStruct.b = 1;
Now I have a struct which is defined in the C++ header file struct.h:
typedef struct
{
double x;
double y;
} myPoint;
typedef struct
{
int num_points;
myPoint *points; // pointer to array of myPoint-structs
} myStruct;
I don't know how to represent the pointer of the C++ struct in Matlab. As I need to define the struct in Matlab I am trying things like:
coder.cstructname(matlab_myPoint,'myPoint','extern');
coder.cstructname(matlab_myStruct,'myStruct','extern');
matlab_myPoint= struct('x',0,'y',0);
matlab_myStruct = struct('num_points',2,'points',myPoint);
ending in an error message
error C2440: '=' : cannot convert from 'myPoint' to 'myPoint *'
In the original C++ struct, a Pointer to an array of structs is used. How can I reproduce this relationship in a Matlab-born struct ? Thank you!
I could finally solve the issue by not passing objects or pointer to objects from Matlab to C but handing over structs instead. The struct in my case contains all the data I need to initialize a new object of the desired class in c.
In order to achieve this one needs to use the same struct architecture in Matlab and in C.
Then with
coder.cstructname(matlab_struct_name,'c_struct_name','extern');
one tells the compiler which C struct is defined by which Matlab struct. The C-Header file has to be specified in the Simulink properties.
The call of the C-Code in Matlab finally looks like this:
coder.ceval('gateway', 1, coder.ref(matlab_struct_name), ,coder.wref(matlab_myRet));
where matlab_myRet has been created the same way like matlab_struct_name and represents the return value struct. All values which are written to it inside the C-Code can later be obtained within Matlab:
matlab_myRet.x(1:5);
matlab_myRet.y(1:5);
Finally an example of the used struct:
in Matlab:
matlab_struct_name.x = 123;
matlab_struct_name.y = 456;
matlab_myRet.x = zeros(10,1);
matlab_myRet.y = zeros(10,1);
in C-Code (header):
typedef struct
{
double x[5];
double y[5];
}matlab_struct_name;
typedef struct
{
double x[10];
double y[10];
}myReturn;
Hope this helps

std::map iterator difference between (*pos).second and pos->second [duplicate]

I am reading a book called "Teach Yourself C in 21 Days" (I have already learned Java and C# so I am moving at a much faster pace). I was reading the chapter on pointers and the -> (arrow) operator came up without explanation. I think that it is used to call members and functions (like the equivalent of the . (dot) operator, but for pointers instead of members). But I am not entirely sure.
Could I please get an explanation and a code sample?
foo->bar is equivalent to (*foo).bar, i.e. it gets the member called bar from the struct that foo points to.
Yes, that's it.
It's just the dot version when you want to access elements of a struct/class that is a pointer instead of a reference.
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = malloc(sizeof(struct foo));
var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;
That's it!
I'd just add to the answers the "why?".
. is standard member access operator that has a higher precedence than * pointer operator.
When you are trying to access a struct's internals and you wrote it as *foo.bar then the compiler would think to want a 'bar' element of 'foo' (which is an address in memory) and obviously that mere address does not have any members.
Thus you need to ask the compiler to first dereference whith (*foo) and then access the member element: (*foo).bar, which is a bit clumsy to write so the good folks have come up with a shorthand version: foo->bar which is sort of member access by pointer operator.
a->b is just short for (*a).b in every way (same for functions: a->b() is short for (*a).b()).
foo->bar is only shorthand for (*foo).bar. That's all there is to it.
Well I have to add something as well. Structure is a bit different than array because array is a pointer and structure is not. So be careful!
Lets say I write this useless piece of code:
#include <stdio.h>
typedef struct{
int km;
int kph;
int kg;
} car;
int main(void){
car audi = {12000, 230, 760};
car *ptr = &audi;
}
Here pointer ptr points to the address (!) of the structure variable audi but beside address structure also has a chunk of data (!)! The first member of the chunk of data has the same address than structure itself and you can get it's data by only dereferencing a pointer like this *ptr (no braces).
But If you want to acess any other member than the first one, you have to add a designator like .km, .kph, .kg which are nothing more than offsets to the base address of the chunk of data...
But because of the preceedence you can't write *ptr.kg as access operator . is evaluated before dereference operator * and you would get *(ptr.kg) which is not possible as pointer has no members! And compiler knows this and will therefore issue an error e.g.:
error: ‘ptr’ is a pointer; did you mean to use ‘->’?
printf("%d\n", *ptr.km);
Instead you use this (*ptr).kg and you force compiler to 1st dereference the pointer and enable acess to the chunk of data and 2nd you add an offset (designator) to choose the member.
Check this image I made:
But if you would have nested members this syntax would become unreadable and therefore -> was introduced. I think readability is the only justifiable reason for using it as this ptr->kg is much easier to write than (*ptr).kg.
Now let us write this differently so that you see the connection more clearly. (*ptr).kg ⟹ (*&audi).kg ⟹ audi.kg. Here I first used the fact that ptr is an "address of audi" i.e. &audi and fact that "reference" & and "dereference" * operators cancel eachother out.
struct Node {
int i;
int j;
};
struct Node a, *p = &a;
Here the to access the values of i and j we can use the variable a and the pointer p as follows: a.i, (*p).i and p->i are all the same.
Here . is a "Direct Selector" and -> is an "Indirect Selector".
I had to make a small change to Jack's program to get it to run. After declaring the struct pointer pvar, point it to the address of var. I found this solution on page 242 of Stephen Kochan's Programming in C.
#include <stdio.h>
int main()
{
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = &var;
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f\n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f\n", pvar->x, pvar->y);
return 0;
}
Run this in vim with the following command:
:!gcc -o var var.c && ./var
Will output:
5 - 14.30
6 - 22.40
#include<stdio.h>
int main()
{
struct foo
{
int x;
float y;
} var1;
struct foo var;
struct foo* pvar;
pvar = &var1;
/* if pvar = &var; it directly
takes values stored in var, and if give
new > values like pvar->x = 6; pvar->y = 22.4;
it modifies the values of var
object..so better to give new reference. */
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f\n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f\n", pvar->x, pvar->y);
return 0;
}
The -> operator makes the code more readable than the * operator in some situations.
Such as: (quoted from the EDK II project)
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
struct _EFI_BLOCK_IO_PROTOCOL {
///
/// The revision to which the block IO interface adheres. All future
/// revisions must be backwards compatible. If a future version is not
/// back wards compatible, it is not the same GUID.
///
UINT64 Revision;
///
/// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
///
EFI_BLOCK_IO_MEDIA *Media;
EFI_BLOCK_RESET Reset;
EFI_BLOCK_READ ReadBlocks;
EFI_BLOCK_WRITE WriteBlocks;
EFI_BLOCK_FLUSH FlushBlocks;
};
The _EFI_BLOCK_IO_PROTOCOL struct contains 4 function pointer members.
Suppose you have a variable struct _EFI_BLOCK_IO_PROTOCOL * pStruct, and you want to use the good old * operator to call it's member function pointer. You will end up with code like this:
(*pStruct).ReadBlocks(...arguments...)
But with the -> operator, you can write like this:
pStruct->ReadBlocks(...arguments...).
Which looks better?
#include<stdio.h>
struct examp{
int number;
};
struct examp a,*b=&a;`enter code here`
main()
{
a.number=5;
/* a.number,b->number,(*b).number produces same output. b->number is mostly used in linked list*/
printf("%d \n %d \n %d",a.number,b->number,(*b).number);
}
output is 5
5 5
Dot is a dereference operator and used to connect the structure variable for a particular record of structure.
Eg :
struct student
{
int s.no;
Char name [];
int age;
} s1,s2;
main()
{
s1.name;
s2.name;
}
In such way we can use a dot operator to access the structure variable

memcpy ing float into int

I want to know whether we can memcpy a structure containing 2 float variables into another structure containing 2 int variable. This is what I have wriiten so far
struct stFloat
{
float a;
float b;
};
struct stInt
{
int a;
int b;
};
int main()
{
struct stFloat aa;
aa.a=12.234;
aa.b=673.797;
struct stInt bb;
memcpy(&bb,&aa,sizeof(stFloat));
printf("%d %d\n",bb.a,bb.b);
return 0;
}
But unfortunately I am not getting the desired result. The output that I was expecting is 12 673 but the output looks like some garbage. Can somebody help me resolving this issue.
Thanks
Integer and float have different internal representation, and memcpy is simply a bitwise copy so if you were expecting the numbers to be converted in some way it's not going to happen.
Instead you need to do it yourself, for example by declaring a constructor or function or assignment operator that allows you to assign stfloats to stint. This also allows you to explicitly indicate the conversion you want.
In general it is a bad idea to use memcpy (among other things, because it only works for PODs, and also because you get this sort of problem). It's a C thing that should be avoided in C++.
No, you can't, but you can write a function which will do it for you :
void cpy(struct stFloat *src, struct stInt *dest){
dest->a = (int)src->a;
dest->b = (int)src->b;
}
then, call it by passing your structures by references pointer (else it will only work on copies of the structures) :
struct stFloat f;
struct stFloat i;
cpy(&f,&i);

How can I concatenate two structs type variables in c++? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'e been trying for sometime to concatenate some struct (I defined) type variables into a bigger one. What I got is basically like this:
I have a struct and two variables of type struct**.
I declare a third one struct C and I want to concatenate A and B into C.
What I tried is something like this (I don't have the code in front of me right now so I'll write something very similar with some names changed as I don't remember them.
struct** A, B;
struct** C;
(I know A and B as I receive them by calling another function)
I allocate memory for C like this.
C = (struct**)malloc(sizeof(A)+sizeof(B));
And I move A and B with memcpy like this.
memcpy(&C, &A, sizeof(A));
memcpy(&C + sizeof(A), &C, sizeof(B));
It's obvious that what I've done is not correct as it seems after all of this C contains only A.
I'm pretty sure the problem is from "**", I can't handle pointers to pointers that well.
Can anybody give me some advice regarding my issue?
I also don't want to use Handles, I have to use memcpy/memmove.
[update from comment:]
My struct are all the same type.
You already have a struct A a; and a struct B b; defined somewhere.
To concatenate them into a struct C you do this:
struct A a;
struct B b;
struct C{
struct A a;
struct B b;
};
struct C c;
c.a = a;
c.b = b;
No pointers or memcpy required.
Edit: Since a and b are of the same type you can somewhat shorten it to this:
struct Something a, b;
struct C{
struct Something[2];
};
struct C c;
c[0] = a;
c[1] = b;
In C++ you would do something like this:
using C = std::array<Something, 2>;
C c{a, b};
[Best for C]
Just use an array.
Assuming struct A is defined an array on the stack
struct A a1 = {...}; /* some initialisation here */
struct A a2 = {...}; /* more initialisation here */
struct A a[2];
a[0] = a1;
a[1] = a2;
or allocate it dynamically:
struct A * pa = malloc(2 * sizeof *pa);
if (NULL != pa)
{
pa[0] = a1;
pa[1] = a2;
/* use pa */
free(pa);
}
else
{
/* handle malloc error */
}
Well, first off, your code has a bug:
memcpy(&C, &A, sizeof(A));
memcpy(&C + sizeof(A), &C, sizeof(B));
Should probably be
memcpy(&C, &A, sizeof(A));
memcpy(&C + sizeof(A), &B, sizeof(B));
You were copying C back into C rather than B.
Second, if you ever find yourself playing with pointers like this you've probably got a design problem somewhere along the lines. If you REALLY want to merge two structs together, why not have struct C simply contain both struct A and B?
If you REALLY want struct C to have nothing bot primitives, dude, just do the work to assign each field individually. Is it really all that much work? I guess it makes sense to generalize it if you expect these fields to change a lot. But this sort of "clever code" is the exact sort of things which will bite you in the ass later down the line.

Are elements stored in struct are next each other

if i have a struct , say:
struct A {
int a,b,c,d,e;
}
A m;//struct if 5 ints
int n[5];//array of 5 ints.
i know that elements in the array are stored one after other so we can use *(n+i) or n[i]
But in case of struct ,is each element is stored next to each other (in the struct A)?
The compiler may insert padding as it wishes, except before the first item.
In C++03 you were guaranteed increasing addresses of items between access specifiers.
I'm not sure if the access specifier restriction is still there in C++11.
The only thing that is granted is that members are stored in the same order.
Between elements there can be some "padding" the compiler may insert so that each value is aligned with the processor word length.
Different compiler can make different choices also depending on the target platform and can be forced to keep a given alignment by option switches or pragma-s.
Your particular case is "luky" for the most of compiler since int is normally implemented as "the integral that better fits the integer arithmetic of the processor". With this idea, a sequence of int-s is aligned by definition. But that may not be the case, for example if you have
struct test
{
char a;
short b;
long c;
long long d;
};
You can dscovery that (&a)+1 != &b and (&b)+1 != &c or (&b)-1 != &a etc.
What is granted is the progression &a < &b; &b < &c; &c < &d;
Structs members in general are stored in increasing addresses but they are not guaranteed to be contiguous.so elements may not always be contiguous. In the example above, given $base is the base address of the struct the layout will be the following.
a will be stored at $base+0
b will be stored at $base+4
c will be stored at $base+8 ... etc
You can see the typical alignment values at http://en.wikipedia.org/wiki/Data_structure_alignment#Typical_alignment_of_C_structs_on_x86
I have written simple program to show strut elements are next to each other
int main() {
struct S {
int a;
int b;
int c;
};
S s = {1,2,3};
int* p = reinterpret_cast <int *> (&s);
cout<<p[0]<<" "<<p[1]<<" "<<p[2];
return 0;
}
Output : 1,2,3
Remember, [] or *(i+1) are symantic construct, that suits with pointers, not with struct variables directly.
As suggested in Cheers and hth. - Alf's answer, there can be padding, before or after struct elements.