Uncommon syntax? ---"->" - syntax

I was looking at someone else's code and saw something that I'd only been told was a pointer. The thing is the syntax is not pointer syntax. This is the following code:
switch(control)
{
case 'w':
case 'a':
case 's':
case 'd':
execute->backup_grid();// this is the part I was talking about.
execute->fill_space();
execute->update_grid();
execute->fill_space();
execute->find_greatest_tile();
execute->display_grid();
if(execute->full()&&apocalypse)
{
response=-1;
break;
}
else if(execute->block_moves())
{
execute->spawn();
break;
}
else
{
response=0;
break;
}

That is a kind of pointer syntax. In plain C, if you have a pointer to a struct, you can access the value of a member with the "arrow" operator, like this:
struct foo {
int num ;
};
struct foo var ;
struct foo *ptr ;
var.num = 0;
ptr = &var;
printf("%d ", ptr->num); // 0
printf("%d ", (*ptr).num); //0
In essence
ptr->num
is a shorter way of
(*ptr)->num
In your code, you are calling methods with a pointer to some object.

Related

How can I remove the segmentation error in the following code?

In the following code, I am getting the segmentation fault. Whenever the query type is 1, we have to push element into the stack, if it is 2 then we have to pop from stack, and if it is 3 then print the maximum value in the stack.
My guess is that the error is present somewhere in the switch case. However, I am unable to spot it. Please help.
#include<bits/stdc++.h>
using namespace std;
int maxinStack(stack<int> st){
int max=st.top();
for (int i=0;i<st.size();i++){
if(st.top()>max){
max=st.top();
}
st.pop();
}
return max;
}
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
stack<int> s;
int querySize;
cin >> querySize;
vector<int> queryType(querySize);
queue<int> queryData;
for(int i=0;i<querySize;i++){
cin>>queryType[i];
if(queryType[i]==1){
int x;
cin >> x;
queryData.push(x);
}
}
/*for (int j=0;j<querySize;j++){
cout << queryType.at(j)<<" ";
}
cout << endl;
while(!queryData.empty()){
cout << queryData.front()<<" ";
queryData.pop();
}
cout << endl;
*/
for (int j=0;j<querySize;j++){
switch (queryType[j]){
case 1:{
int y=queryData.front();
s.push(y);
queryData.pop();
}
case 2: s.pop();
case 3: cout << maxinStack(s)<<endl;
}
}
return 0;
}
Assuming inputs are correct, I think you forgot to put break at the end of each case handlers.
So it should be something like:
switch (queryType[j]){
case 1:{
int y=queryData.front();
s.push(y);
queryData.pop();
break;
}
case 2: s.pop(); break;
case 3: cout << maxinStack(s)<<endl; break;
}
Otherwise when it handles case 1 it will still fall-through to the next case handlers so it also does case 2 and case 3. This means that the stack is always empty and it causes segmentation fault when it handles query type of 2 - tried to pop for an empty stack.
As pointed above by #Hanjoung, your switch cases are missing break statements. Just to give you a little context on these break statements, if not specified all the cases after the matched case will also run. For eg:
switch(choice){
case 1:
case 2: // Suppose this case matched
case 3: // This will also run as no break in case 2
break;
case 4: // Will not run as break in case 3
default:
}
The reason you are getting segmentation error is because your "case 2" is popping from empty stack, and reason for running of this "case 2" is absence of break statement in "case 1".

How do you perfectly hash a union of a possibly unicode char with a 32-bit integer?

I've never really had the need to create hash function before but right now it seems like the best solution for this.
I haven't tried anything, but I guess what I would try first is to hash take the unicode integer as the least significant 32-bits of a long. Then in the most significant 32-bits, store the integer.
struct Symbol
{
private:
enum Type {
Terminal,
Variable,
}
union {
char m_term;
int m_var;
}
Type m_type;
public:
this(char term) {
m_type = Type.Terminal;
m_term = term;
}
this(int var) {
m_type = Type.Variable;
m_var = var;
}
}
Symbol is the struct I'd like to hash. It contains a union which we should hash to achieve this. Was just wondering if my approach above is correct.
Thanks to commenters.
bool opEquals(Symbol sym) const {
if (m_type == Type.Terminal)
return m_term == sym.m_term;
else
return m_var == sym.m_var;
}
ulong toHash() {
ulong bit = m_type;
ulong key;
if (m_type == Type.Terminal)
key = cast(ulong) m_term;
else
key = m_var;
return bit | (key << 1);
}

How to solve the "R0 invalid mem access 'inv'" error when loading an eBPF file object

I'm trying to load an eBPF object in the kernel with libbpf, with no success, getting the error specified in the title. But let me show how simple my BPF *_kern.c is.
SEC("entry_point_prog")
int entry_point(struct xdp_md *ctx)
{
int act = XDP_DROP;
int rc, i = 0;
struct global_vars *globals;
struct ip_addr addr = {};
struct some_key key = {};
void *temp;
globals = bpf_map_lookup_elem(&globals_map, &i);
if (!globals)
return XDP_ABORTED;
rc = some_inlined_func(ctx, &key);
addr = key.dst_ip;
temp = bpf_map_lookup_elem(&some_map, &addr);
switch(rc)
{
case 0:
if(temp)
{
// no rocket science here ...
} else
act = XDP_PASS;
break;
default:
break;
}
return act; // this gives the error
//return XDP_<whatever>; // this works fine
}
More precisely, the libbpf error log is the following:
105: (bf) r4 = r0
106: (07) r4 += 8
107: (b7) r8 = 1
108: (2d) if r4 > r3 goto pc+4
R0=inv40 R1=inv0 R2=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R3=pkt_end(id=0,off=0,imm=0) R4=inv48 R5=inv512 R6=inv1 R7=inv17 R8=inv1 R10=fp0,call_-1 fp-16=0 fp-32=0 fp-40=0
109: (69) r3 = *(u16 *)(r0 +2)
R0 invalid mem access 'inv'
I really don't see any problem here. I mean, this is so so simple, and yet it breaks. Why shouldn't this work? What am I missing? Either the verifier went crazy, or I'm doing something very stupid.
Ok, so, after 3 days, more precisely 3 x 8 hrs = 24 hrs, worth of code hunting, I think I've finally found the itching problem.
The problem was in the some_inlined_func() all along, it was more tricky then challenging. I'm writing down here a code template explaining the issue, so others could see and hopefully spend less then 24 hrs of headache; I went through hell for this, so stay focused.
__alwais_inline static
int some_inlined_func(struct xdp_md *ctx, /* other non important args */)
{
if (!ctx)
return AN_ERROR_CODE;
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth;
struct iphdr *ipv4_hdr = NULL;
struct ipv6hdr *ipv6_hdr = NULL;
struct udphdr *udph;
uint16_t ethertype;
eth = (struct ethhdr *)data;
if (eth + 1 > data_end)
return AN_ERROR_CODE;
ethertype = __constant_ntohs(eth->h_proto);
if (ethertype == ETH_P_IP)
{
ipv4_hdr = (void *)eth + ETH_HLEN;
if (ipv4_hdr + 1 > data_end)
return AN_ERROR_CODE;
// stuff non related to the issue ...
} else if (ethertype == ETH_P_IPV6)
{
ipv6_hdr = (void *)eth + ETH_HLEN;
if (ipv6_hdr + 1 > data_end)
return AN_ERROR_CODE;
// stuff non related to the issue ...
} else
return A_RET_CODE_1;
/* here's the problem, but ... */
udph = (ipv4_hdr) ? ((void *)ipv4_hdr + sizeof(*ipv4_hdr)) :
((void *)ipv6_hdr + sizeof(*ipv6_hdr));
if (udph + 1 > data_end)
return AN_ERROR_CODE;
/* it actually breaks HERE, when dereferencing 'udph' */
uint16_t dst_port = __constant_ntohs(udph->dest);
// blablabla other stuff here unrelated to the problem ...
return A_RET_CODE_2;
}
So, why it breaks at that point? I think it's because the verifier assumes ipv6_hdr could potentially be NULL, which is utterly WRONG because if the execution ever gets to that point, that's only because either ipv4_hdr or ipv6_hdr has been set (i.e. the execution dies before this point if it's the case of neither IPv4 nor IPv6). So, apparently, the verifier isn't able to infer that. However, there's a catch, it is happy if the validity of also ipv6_hdr is explicitly checked, like this:
if (ipv4_hdr)
udph = (void *)ipv4_hdr + sizeof(*ipv4_hdr);
else if (ipv6_hdr)
udph = (void *)ipv6_hdr + sizeof(*ipv6_hdr);
else return A_RET_CODE_1; // this is redundant
It also works if we do this:
// "(ethertype == ETH_P_IP)" instead of "(ipv4_hdr)"
udph = (ethertype == ETH_P_IP) ? ((void *)ipv4_hdr + sizeof(*ipv4_hdr)) :
((void *)ipv6_hdr + sizeof(*ipv6_hdr));
So, it seems to me there's something strange about the verifier here, because it's not smart enough (maybe neither it needs to be?) to realize that if it ever gets to this point, it's only because ctx refers either an IPv4 or IPv6 packet.
How does all of this explain the complaining over return act; within the entry_point()? Simple, just bear with me. The some_inlined_func() isn't changing ctx, and its remaining args aren't used either by entry_point(). Thus, in case of returning act, as it depends on the some_inlined_func() outcome, the some_inlined_func() gets executed, with the verifier complaining at that point. But, in case of returning XDP_<whatever>, as the switch-case body, and neither the some_inlined_func(), doesn't change the internal state of the entry_point() program/function, the compiler (with O2) is smart enough to realize that there's no point in producing assembly for some_inlined_func() and the whole switch-case (that's the O2 optimization over here). Therefore, to conclude, in case of returning XDP_<whatever>, the verifier was happy as the problem actually lies into some_inlined_func() but the actual produced BPF assembly doesn't have anything of that, so the verifier didn't checked some_inlined_func() because there wasn't any in the first place. Makes sense?
Is such BPF "limitation" known? Is out there any document at all stating such known limitations? Because I didn't found any.

Pointer not printing char[] array

I'm writing some code to take in a string, turn it into a char array and then print back to the user (before passing to another function).
Currently the code works up to dat.toCharArray(DatTim,datsize); however, the pointer does not seem to be working as the wile loop never fires
String input = "Test String for Foo";
InputParse(input);
void InputParse (String dat)
//Write Data
datsize = dat.length()+1;
const char DatTim[datsize];
dat.toCharArray(DatTim,datsize);
//Debug print back
for(int i=0;i<datsize;i++)
{
Serial.write(DatTim[i]);
}
Serial.println();
//Debug pointer print back
const char *b;
b=*DatTim;
while (*b)
{
Serial.print(*b);
b++;
}
Foo(*DatTim);
I can't figure out the difference between what I have above vs the template code provided by Majenko
void PrintString(const char *str)
{
const char *p;
p = str;
while (*p)
{
Serial.print(*p);
p++;
}
}
The expression *DatTim is the same as DatTim[0], i.e. it gets the first character in the array and then assigns it to the pointer b (something the compiler should have warned you about).
Arrays naturally decays to pointers to their first element, that is DatTim is equal to &DatTim[0].
The simple solution is to simply do
const char *b = DatTim;

scanf,fgets, fgetc get skipped inside loop

Im trying to make a recursive menu.
This program will later work with a tree(hojanodo), thats why I keep track of the root.
Problem: For some reason the fgets/fgetc is being skipped inside the recursivity on the second run, why does this happen?
I want the user to input either 1,2 or 3.(int)
What would be the fix for this? and is this the best way to implement a menu?
Here's what I have right now:(It compiles and runs so you can test it out but doesn't really work like I would like to..)
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
char ch;
int i;
struct node *left;
struct node *right;
}hojaNodo;
int handle_menu(int eventHandler, hojaNodo **root);
int opcion_menu();
char get_symbol();
int get_userMenuInput();
int intro();
int main(){
hojaNodo *treeRoot = NULL;
intro();
// system("clear");
handle_menu(opcion_menu(), &treeRoot);
return 0;
}
int opcion_menu(){
int userOption;
printf("1.Agrega un Simbolo.\n");
printf("2.Listar Codigo\n");
printf("3.Exit");
userOption = get_userMenuInput();
printf("User: %d",userOption);
if(userOption < 4 && userOption > 0){
return userOption;
}
else
return -1;
}//eof opcion_menu
int handle_menu(int userOption,hojaNodo **root){
hojaNodo *tempRoot = NULL;
tempRoot = *root;
int valor;
char simbol;
switch(userOption){
case 1:
simbol = get_symbol();
printf("Simbol: %c", simbol);
break;
case 2:
printf("List Nodes\n");
break;
case 3:
printf("Exit");
userOption = -1;
// destroy_tree(root);
break;
default:
printf("userOption Error, Bye!");
break;
}//eof switch
if(userOption != -1)
handle_menu(opcion_menu(),&tempRoot);
// return userOption;
return -1;
}//eof menu()
char get_symbol(){
/*char userKey[3]
fgets(userKey,len,stdin);*/
char simbolo;
printf("Give me a symbol.");
simbolo = fgetc(stdin);
return simbolo;
}
int get_userMenuInput(){
char userKey[3];
int userOption;
size_t len;
len = sizeof(userKey);
fgets(userKey,len,stdin);
userOption = atoi(userKey);
//printf("User Option: %d\n", userOption);
return userOption;
}
Well apart from all the comments related to recursion and other changes suggested, please check this out. fgets() function needs flushing the input stream. It can be done using fflush() or fgetc().
A simple solution would be:
In function:
int opcion_menu(){
...
fgets(userKey,2,stdin);
fgetc(stdin); // Add this statement
Also in function:
int handle_menu(int userOption,hojaNodo **root)
case 1:
printf("Give me a choice : ");
fgets(userKey,2,stdin);
fgetc(stdin); // add this statement
fgets reads in at most one less than size characters from stream and stores them into the buffer pointed to by string. This will lead the newline character still available in Input Stream which need to be flushed. If this newline character is not read from Input stream, than this would become the input for next fgets function and ultimately it will skip the fgets(since it has already got its input a newline character)
fgetc(stdin) will flush out these extra newline character.
I don't know if this might help anyone.
In my case, I had to 'free' the buffer from the char with this function:
void clean(){
char cTemp;
while((cTemp = getchar()) != '\n')
;
}
Im not really sure why this works but it does(if anyone does, please add it to my answer).
I call it right before I call get_userOption();

Resources