Function struct points to other function of other struct [duplicate] - c++

This question already has answers here:
struct pointer function points to other function of other struct
(3 answers)
Closed 6 years ago.
I'm trying to point a structure function to another function of another structure,
Plase consider this:
// Main Structure:
typedef struct
{
int GetValA(int a)
{
return a * 2;
}
} x;
typedef struct
{
int(*HGetValA)(int); // Pointer function
} hookx;
// Then
int main()
{
x v1;
hookx* v2;
v2 = (hookx*)&v1; // or 0x0 memory address
// Now declaring pointer function
v2->HGetValA = (int(*)(int))&v1.GetValA; // Pointing to function of the main structure.
}
for me, this looks good, but at compile time gives me the error:
[Warning] converting from 'int (x::)(int)' to 'int ()(int)'
[-Wpmf-conversions]

The pointer points to a member from class/struct does NOT really means to a address, it just points as an offset from this.
So the pointer type out of the class/struct (like in your code, int ()(int)) is different from the inner (like, int (::)(int)).
You have to declare the pointer with a class/struct name that seem to be a scope (and it does).

Related

C++ object looks like its being used as struct [duplicate]

This question already has answers here:
What is the use of Struct Tag name in C programming?
(3 answers)
What are the advantages of differentiating type/tag names for a typedef in C?
(3 answers)
Does typedef of a structure without tag creates distinct type each time it is used and if not why?
(2 answers)
Closed 6 months ago.
In the following code, I thought saCmdQueue_s is a struct and saCmdQueue_t is an object of type saCmdQueue_s. But then I see the last line looks like they are using saCmdQueue_t to set the type for an object named sa_queue[SA_QSIZE]. Can some help me understand.
typedef struct saCmdQueue_s {
uint8_t *buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
static saCmdQueue_t sa_queue[SA_QSIZE];
In C++, when struct is declared, usage is different according to declare type.
If struct is declared as typedef type, you can write other name at the end of struct. Other name is the new name of the type - struct you declared.
Otherwise, if struct is declared as usual type, the result is the following.
struct saCmdQueue_s {
uint8_t* buf;
int len;
} saCmdQueue_t;
#define SA_QSIZE 6 // 1 heartbeat (GetSettings) + 2 commands + 1 slack
saCmdQueue_t sa_queue[SA_QSIZE];
Error: variable "saCmdQueue_t" is not a type name
If you write typedef in front of struct, the struct is declared the type like data type(int, char, string, vector, ...).

C++ returning uint16_t array from function causes segmentation fault [duplicate]

This question already has answers here:
Returning a pointer of a local variable C++
(5 answers)
Closed 7 months ago.
uint16_t * getRegister(std::string reg) {
// unordered_map<string, vector<uint16_t>> current_reg_map;// defined globally.
// vector current_reg_map has minimum 2 values;
uint16_t regval[current_reg_map[reg].size()];
std::copy(current_reg_map[reg].begin(), current_reg_map[reg].end(), regval);
return regval;
}
int main() {
std::string regname = "4400";
uint16_t *tmp = reader.getRegister2(regname, tmp);
std::cout<<"result "<<tmp[0]<<"\t"<<tmp[1]<<std::endl;
}
Throws segmentation fault at runtime. A lot of posts in stack overflow suggests returning a vector instead. But I explicitly require a uint16_t array as this module is part of a larger project.
You cannot return an array from a function in C++. Your function returns a pointer. But that pointer points to an array which has been destroyed (after you left the function where it was declared). Therefore you get a segmentation fault.
The C++ solution is to use a vector
std::vector<uint16_t> getRegister(std::string reg) {
std::vector<uint16_t> regval(current_reg_map[reg].size());
std::copy(current_reg_map[reg].begin(),
current_reg_map[reg].end(),
regval.begin());
return regval;
}
int main(){
std::string regname = "4400";
std::vector<uint16_t> tmp = reader.getRegister2(regname);
std::cout<<"result "<<tmp[0]<<"\t"<<tmp[1]<<std::endl;
}
This is one of the methods I found to achieve what I was looking for.
Instead of returning an array from the function, I can create an array in the main function and pass it as an argument.
int getRegister(std::string reg, uint16_t *arr){
// unordered_map<string, vector<uint16_t>> current_reg_map;// defined globally.
// vector current_reg_map has minimum 2 values;
std::copy(current_reg_map[reg].begin(), current_reg_map[reg].end(), arr);
return current_reg_map[reg].size();
}
int main(){
std::string regname = "4400";
uint16_t tmp[2];
int i = reader.getRegister2(regname, tmp); // returns size of array.
std::cout<<"result"<<tmp[0]<<"\t"<<tmp[1]<<std::endl;
}
You must not return the address/reference to a local variable inside a function because it doesn't exist outside the scope of that function. Both of these examples are wrong:
int *foo() {
int a;
return &a;
}
int& bar() {
int b;
return b;
}
Unless you inhibit all warning messages from the compiler, you should get this warning:
warning: address of local variable 'a' returned [-Wreturn-local-addr]
warning: reference to local variable 'b' returned [-Wreturn-local-addr]
If you need to return the address of a local variable, you need to dynamically allocate the memory for that variable.
int *foo() {
int *a = new int;
return a;
}
But remember to free/deallocate the allocated memory. If you need a simpler solution, you can use STL containers or smart pointers.

What does this nested struct declaration mean? [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 3 years ago.
Improve this question
#include <bits/stdc++.h>
using namespace std;
struct {
struct {
struct {
char *OwO[12];
}iwi;
}uwu;
}owo;
int main() {
*owo.uwu.iwi.OwO = "What's this?";
printf("%s\n", *owo.uwu.iwi.OwO);
return 0;
}
Hi guys I don't know how this code actually work? Can anyone explain this to me?
Consider for example this declaration
struct {
char *OwO[12];
}iwi;
It at first declares an unnamed structure with one data member that has the type of an array with 12 elements of the type char *. And then it declares an object named iwi of the structure.
So to access the data member OwO of the object iwi you can use the expression
iwi.OwO
that returns lvalue of the array OwO.
If to apply the operator * to the expression then the array OwO is implicitly converted to pointer to its first element and has the type char **. Dereferencing the pointer we get the first element of the array of the type char *.
We can assign the element with a string literal as
*iwi.OwO = "What's this?";
That is the first element of the array that has the type char * now gets the address of the string literal.
Here is a demonstrative program
#include <stdio.h>
struct {
char *OwO[12];
} iwi;
int main(void)
{
*iwi.OwO = "What's this?";
printf( "%s\n", *iwi.OwO );
return 0;
}
Its output is
What's this?
In the original code this unnamed structure is included into two other unnamed structures
struct {
struct {
struct {
char *OwO[12];
}iwi;
}uwu;
}owo;
That is with have object owo of the unnamed outer structure that has data member uwu of the enclosed unnamed data structure that in turn has data member iwi of the most inner unnamed structure.
So to access the data member OwO we have to list all names of object
owo.uwu.iwi.OwO
So we have gotten an access to the most inner data member OwO. And now dereferncing the expression as it was shown in the demonstrative program above we initialize the first element of the array with the string literal "What's this?".
And in the same way we can output it using this full expression
printf("%s\n", *owo.uwu.iwi.OwO);
It's several nested unnamed struct types.
Here is the same thing using named types, and indexing instead of dereferencing.
struct Inner
{
char* OwO[12];
};
struct Middle
{
Inner iwi;
};
struct Outer
{
Middle uwu;
};
Outer owo;
int main() {
owo.uwu.iwi.OwO[0] = "What's this?";
printf("%s\n", owo.uwu.iwi.OwO[0]);
return 0;
}

C++ function calling to 2d array [duplicate]

This question already has answers here:
Passing a 2D array to a C++ function
(18 answers)
Closed 7 years ago.
I have in class County.h constructor:
struct Country {
Country(double**, int);
};
and in main I have graph[Size][Size] and I want to call the constructor for County.
int main() {
double graph[Size][Size];
Country c(graph, 0);
}
But its giving me error no matching function for call to ‘County::County(double [22][22], int)’
What I can do in order to solve this problem?
double [Size][Size] and double** are not at all the same type. That is what your compiler doesn't like.
Change your constructor prototype or the way you declare your array. But you cannot directly cast an array of array to a pointer of pointer.
struct Country {
Country(double[Size][Size], int);
};
OR:
int main() {
double** graph = new (double*)[Size];
for (int i = 0; i < Size; ++i) {
graph[i] = new double[Size];
}
Country c(graph, 0);
// Don't forget to delete your graph then.
}
Note that the first one requires that you would know the size before your code start its execution (storing Size in a macro for instance), but the second one is longer to code, and you will have to manipulate more RAM memory, that can lead to mistakes if you are not careful.
An alternative is to declare your constructor as a template and pass the array by (const) reference,
struct Country {
template<size_t N>
Country(double /*const*/ (&arr)[N][N], int);
};
In this way, the template will deduce the size of the array directly. Of course, the downside is that the above won't work with double pointers. The upside is that the compiler will strongly check the type and your program won't even compile if the array is not made of doubles (no conversions are being performed at type deduction) or if it is not square.

C++ - Is an array a pointer? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C: differences between pointer and array
Is an array in C++ a pointer? Can you clarify this?
Thanks.
No. But it can decay to a pointer whenever you need it.
void foo1(char * c) {
}
int main() {
char Foo[32];
foo1(Foo); // Foo decays to a pointer
char * s = Foo; // Foo decays to a pointer which is assigned to s
}
The array name itself without any index is a pointer.
int a[10];
printf("%d\n",*a); // will print first value
printf("%d\n",*(a+1) ); // will print second value