#define NUMBER_OF_CARDS 54
typedef enum type{
QUEEN;
JACK;
KING
} CardTypes;
typedef struct game{
CardTypes cards[NUMBER_OF_CARDS];
struct{
int hearts;
int spades;
int clubs;
int diamonds;
}
int players_cards;
}GameState;
I have something similar like this and I want to access any variable from enum when this function is called
void set_cards(GameState gamestate, int x, int y, CardTypes cardtypes){
gamestate.cards[x * y] = cardtypes;
}
void generate_game(GameState gamestate){
/*
some code
*/
if(variable == 0){
set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK;
//This is what I have tried but it doesn't work
I hope you understand what I mean, because I really don't know how to explain this any better.
set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK;
//this is what I have tried but it doesn't work
please ignore any inaccuracies in the code. what is important for me is how can i access any of the enum's variable in the function generate_game().
this right here: if(variable == 0){ set_cards(gamestate, x, y, gamestate.cards[NUMBER_OF_CARDS].JACK; //This is what I have tried but it doesn't work
Based upon what #Aconcagua wrote your code should be using pointers :
// gamestate is a structure , so it must be passed as pointer to enable modification to be seen by caller
void set_cards(GameState *gamestate, int x, int y, CardTypes cardtypes){
gamestate->cards[x * y] = cardtypes;
}
void generate_game(GameState *gamestate){ // here also pointer so caller know the changes
/*
some code
*/
if(variable == 0){
// next depends on what you intend to do :
// 1- set the current games rate card with value of last card
set_cards(gamestate, x, y, gamestate->cards[NUMBER_OF_CARDS-1]);
// 2- set the current gamestate to JACK
set_cards(gamestate, x, y, JACK);
Your types do not have too much sense. Card is defined by its colour and type.
typedef enum {
QUEEN,
JACK,
KING,
//you neeed some more
} CardTypes;
typedef enum {
HEART,
SPADE,
CLUB,
DIAMOND,
} CardColour;
typedef struct
{
CardTypes type;
CardColur colour;
}Card;
Card deck[54];
How to access:
void foo(Card *card)
{
Card card1;
card1.colour = HEART;
card1.type = JACK;
card -> colour = DIAMOND;
card -> type = KING;
card[34].colour = CLUB;
card[34].type = QUEEN;
}
Related
so I've got a buggy C file in which i need to find an exploit. I have found a bug when accessing the following struct:
#define BOARD_SIZE 10
typedef int (*turn_function_t)(struct board *);
typedef void (*win_function_t)(struct board *);
struct board {
uint8_t f1[BOARD_SIZE][BOARD_SIZE];
uint8_t f2[BOARD_SIZE][BOARD_SIZE];
win_function_t win;
turn_function_t turn;
int avail;
};
int do_shot(struct board *board, int strength, int x, int y) {
if(!(x >= 0 && x <= BOARD_SIZE && y >= 0 && y <= BOARD_SIZE)) {
return SHOT_ERR_EINVAL;
}
/* If there was already a sunken ship, return error */
if(board->f1[x][y] && !board->f2[x][y])
return SHOT_ERR_SUNKEN;
/* Now perform shot */
if(!board->f2[x][y])
return SHOT_WATER;
board->f2[x][y] -= strength;
if(!board->f2[x][y])
return SHOT_SUNKEN;
return SHOT_HIT;
}
The bug I found is a wrong index check when accessing array f2. I can chose the index as input (index can be anything from 0 to 10 inclusive). I need to find a way to call the function win (doesn't matter which parameter). My question now is is there any way I can use that out of bounds access to call the function win since the function pointer is stored directly after the array f2 inside the struct?
of cause it can be done easily.
I show you an example code below.
I use pragma pack(1) for byte align and use print to find the address of the function, and finally I got it.
the code may can not be run on your computer.
but your can find the address by print to make bounds address equal to function address.
it may be f[0][-1] on your computer
#include <stdio.h>
typedef int (*turn_function_t)(struct board *);
#pragma pack(1)
struct board
{
turn_function_t win;
int f[10][10];
};
#pragma pack(0)
int win(struct board *b)
{
printf("Win!\n");
return 0;
}
int main()
{
struct board b;
b.win = win;
// printf("%p\n", &b.f[0][-2]);
// printf("%p\n", &b.win);
(*(turn_function_t *)(&b.f[0][-2]))(&b);
return 0;
}
I am trying to define a structure in C for a square where each side can either have a given color (labeled by int) or not have any color at all.
I would like my struct to behave like a named tuple, i.e allow for referring to the north color by square.n = 0; or square.c[NORTH_DIRECTION] = 0; interchangeably.
Is the following a correct way to do it:
typedef struct {
union {
struct {
int n, e, s, w;
};
int c[4];
};
union {
struct {
bool n_is_null, e_is_null, s_is_null, w_is_null;
};
bool is_null[4];
};
} SquareColors;
Thank you very much!
I've been working on creating my own GUI library for MS-DOS on my free time and I got stuck on how I can implement an array that would contain structures of GUI elements.
So far I was able to make it draw the window itself, but I needed a way to draw the elements inside the window such as text boxes, text labels, buttons, ect.
Here's my current code:
#include <stdio.h>
#include <conio.h>
#include <malloc.h>
#include <string.h>
#include "graph.h" //Watcom graphics library
#define false 0
#define true 1
#define border_none 0
#define border_out 1
#define border_in 2
struct text_button {
char text[128];
int pos_x;
int pos_y;
int size_x;
int size_y;
int text_color;
int button_color;
};
struct window_structure {
char title[128];
int pos_x;
int pos_y;
int pre_pos_x;
int pre_pos_y;
int size_x;
int size_y;
int min_size_x;
int min_size_y;
int max_size_x;
int max_size_y;
int show_tab;
int border_type;
int focused;
//Right here is where I would add the array containing the elements.
};
void draw_border(int type,int pos_x,int pos_y,int size_x,int size_y) {
int c_1,c_2;
if (type==1) {
c_1=15;
c_2=0;
} else if (type==2) {
c_1=0;
c_2=15;
}
if (type!=0) {
_setcolor(c_1);
_moveto(pos_x,pos_y);
_lineto(pos_x+size_x,pos_y);
_moveto(pos_x,pos_y);
_lineto(pos_x,pos_y+size_y);
_setcolor(c_2);
_moveto(pos_x+size_x,pos_y+size_y);
_lineto(pos_x+size_x,pos_y);
_moveto(pos_x+size_x,pos_y+size_y);
_lineto(pos_x,pos_y+size_y);
}
}
void draw_box(int type,int color,int pos_x,int pos_y,int size_x,int size_y) {
_setcolor(color);
_rectangle(_GFILLINTERIOR,pos_x,pos_y,pos_x+size_x,pos_y+size_y);
draw_border(type,pos_x-1,pos_y-1,size_x+2,size_y+2);
}
struct window_structure create_window(
char title[],
int pos_x,
int pos_y,
int size_x,
int size_y,
int min_size_x,
int min_size_y,
int max_size_x,
int max_size_y,
int show_tab,
int border_type
) {
struct window_structure window;
strcpy(window.title,title);
window.pos_x=pos_x;
window.pos_y=pos_y;
window.pre_pos_x=pos_x;
window.pre_pos_y=pos_y;
window.size_x=size_x;
window.size_y=size_y;
window.min_size_x=min_size_x;
window.min_size_y=min_size_y;
window.max_size_x=max_size_x;
window.max_size_y=max_size_y;
window.show_tab=show_tab;
window.border_type=border_type;
window.focused=true;
return window;
}
void draw_window(struct window_structure window) {
int offset_x,offset_y;
if (window.size_x<window.min_size_x) {
window.size_x=window.min_size_x;
} else if (window.size_x>window.max_size_x) {
window.size_x=window.max_size_x;
}
if (window.size_y<window.min_size_y) {
window.size_y=window.min_size_y;
} else if (window.size_y>window.max_size_y) {
window.size_y=window.max_size_y;
}
if (window.show_tab==true) {
int tab_color;
if (window.focused==true) {
tab_color=9;
} else {
tab_color=8;
}
draw_box(
window.border_type,
tab_color,
window.pos_x,
window.pos_y-1,
window.size_x-1,
18
);
offset_x=0;
offset_y=20;
}
draw_box(
window.border_type,
7,
window.pos_x+offset_x,
window.pos_y+offset_y,
window.size_x-1,
window.size_y-1
);
//Once the window has been drawn, the next part it would do here is draw the elements
window.pre_pos_x=window.pos_x;
window.pre_pos_y=window.pos_y;
}
I know MS-DOS is quite outdated, this is just for my hobby. I'm currently using Open Watcom as my compiler.
//Right here is where I would add the array containing the elements.
You know, since you'll have a variable number of elements, you can't declare a fixed-size array here, so you can just declare a pointer and allocate the array as needed. You'll also need to store the number of elements allocated.
struct window_structure
{
…
int nelem; // how many elements are there
struct element *elements; // pointer to allocated elements
};
Both shall be initialized to 0.
struct window_structure create_window(…)
{
…
window.nelem = 0;
window.elements = NULL;
return window;
}
The struct element type could be defined as
struct element
{ enum elemtype { text_button, /* add other types here */ } elemtype;
union
{ struct text_button tb;
/* add other types here */
} u;
};
An element, e. g. a text_button, could then be added to the window with
struct element *new;
new = realloc(window.elements, (window.nelem+1) * sizeof *new);
if (!new) exit(1); // or some better error handling
window.elements = new;
window.elements[window.nelem].elemtype = text_button;
window.elements[window.nelem].u.tb = your_text_button_to_add;
++window.nelem;
//Once the window has been drawn, the next part it would do here is draw the elements
This would then be done like
int i;
for (i = 0; i < window.nelem; ++i)
switch (window.elements[i].elemtype)
{
case text_button:
/* draw the text_button window.elements[i].u.tb here */
break;
/* add cases for other element types here */
}
Based on the answer to the question Passing variable type as function parameter:
I could write something like this:
enum {
TYPEA,
TYPEB,
TYPEC,
TYPED
} TYPE;
void foo(TYPE t, void* x){
switch(t){
case TYPEA:
struct A* y = (struct A*)x;
//do something with a member named "next"
break;
case TYPEB:
struct B* y = (struct B*)x;
//do something with a member named "next"
...
}
}
Is there any way to avoid rewriting the "something with a member named next" multiple times?
We are assuming that "next" in A and B are not in the same relative memory position in each struct.
Assuming the items of the enum aren't given custom numbers, you can do a compact version of a switch-statement, by using function pointers.
enum {
TYPEA,
TYPEB,
TYPEC,
TYPED,
TYPE_N // number of enum items
} TYPE;
typedef void(*type_func_t)(void*);
static void TYPEA_specific (void* x)
{
struct A* y = x;
// specific stuff related to TYPEA here
do_something_with_next(y->next);
}
static void TYPEB_specific (void* x)
{
struct B* y = x;
// specific stuff related to TYPEB here
do_something_with_next(y->next);
}
static const type_func_t TYPE_HANDLER [TYPE_N] =
{
TYPEA_specific,
TYPEB_specific
...
};
inline void foo (TYPE t, void* x)
{
TYPE_HANDLER[t](x);
}
This solution uses a macro:
#include <stdio.h>
#define POLYCAST_AB(etype, target, member) \
*((etype) == TYPEA ? &((struct A *)(target))->member : \
(etype) == TYPEB ? &((struct B *)(target))->member : 0)
enum TYPE {
TYPEA,
TYPEB
};
struct A {
int next;
} a = {42};
struct B {
int i;
int next;
} b = {43, 44};
static void foo(enum TYPE t, void *x) {
POLYCAST_AB(t, x, next) += 100; // <-- most other answers can't do this
printf("next=%d\n", POLYCAST_AB(t, x, next));
}
int main(void) {
foo(TYPEA, &a);
foo(TYPEB, &b);
return 0;
}
If you don't need an lvalue, you can omit the extra * and & in the macro definition (and also omit the assumption that the next all have the same type).
C doesn't have dynamic look-up of structure members, of course.
The solution that will save the most keystrokes is probably to use a macro.
Also, there's no point in casting the pointer when converting from void *.
In each case, you can take the address of next with &y.next and then either pass it to a function or transfer control to code that uses the pointer to do something with next. This presumes that next has the same type in each struct, although it may be in different locations.
Here are three examples:
// Example 0: Functional call.
switch(t)
{
case TYPEA:
MyFunction(&(struct A *)x->next);
break;
case TYPEB:
MyFunction(&(struct B *)x->next);
break;
}
// Example 1: Code after the switch.
TypeOfNext *next;
switch(t)
{
case TYPEA:
next = &(struct A *)x->next;
break;
case TYPEB:
next = &(struct B *)x->next;
break;
}
… code that uses next…
// Example 2: Code in the switch, with goto.
switch(t)
{
TypeOfNext *next;
case TYPEA:
next = &(struct A *)x->next;
goto common;
case TYPEB:
next = &(struct B *)x->next;
common:
… code that uses next…
break;
}
I have this call on a file called 'PlayBoard.c':
MoveSucc = putBoardSquare(theBoard, getX, getY, nextTurn);
Where 'theBoard' is a pointer to struct Board. Inside the function I am changing the board's size by referencing the pointer to ANOTHER Board struct, a bigger one. Will it change 'theBoard' on 'PlayBoard.c', where MoveSucc is invoked?
EDIT: putBoardSquare is defined in another source file
EDIT: I've added the relevant functions
Boolean putBoardSquare(BoardP theBoard, int X, int Y, char val)
{
if (val != 'X' && val != 'O')
{
reportError(BAD_VAL);
return FALSE;
}
if (X<0 || Y<0)
{
reportError(OUT_OF_BOUND);
return FALSE;
}
if (X>theBoard->height || Y>theBoard->width)
{
theBoard = expandBoard(theBoard, X,Y);
}
printf("BOARD SIZE IS %d*%d\n",theBoard->height,theBoard->width);
if (theBoard->board[X][Y] == 'X' || theBoard->board[X][Y] == 'Y' )
{
reportError(SQUARE_FULL);
return FALSE;
}
if (val != turn)
{
reportError(WRONG_TURN);
return FALSE;
}
theBoard->board[X][Y] = val;
printf("PUT %c\n",theBoard->board[X][Y]);
changeTurn(val);
return TRUE;
}
static BoardP expandBoard(ConstBoardP theBoard, int X, int Y)
{
int newWidth = theBoard->width;
int newHeight = theBoard->height;
if (X>theBoard->height)
{
newHeight = (newHeight+1) * 2;
}
if (Y>theBoard->width)
{
newWidth = (newWidth+1) * 2;
}
BoardP newBoard = createNewBoard(newWidth,newHeight);
copyBoard(theBoard,newBoard);
printf("RETUNRNING NEW BOARD OF SIZE %d*%d\n",newHeight,newWidth);
return newBoard;
}
As you can see, when the user tries to place 'X' or 'O' outside the board, it needs to be expanded which happens (I know cause I've printed new board's size in expandBoard() and in putBoardSquare()). But the pointer in 'PlayBoard.c' doesn't seem to change anyway....
My question: how can I change the pointer of a struct passed as an argument to another function? In 'PlayBoard.c' I pass one struct as an argument, and I want putBoardSquare to refrence it to another struct, which will take effect in PlayBoard.c as well.
Am I clear?
EDIT
theBoard = expandBoard(theBoard, X,Y);
This assignment only changes a local variable. You'll have to add one level of indirection, as in:
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
Boolean putBoardSquare(BoardP *theBoard, int X, int Y, char val)
{
/* ... */
*theBoard = expandBoard(theBoard, X,Y);
/* ... */
}
Your question is confusing (perhaps you should post the code you have), but the error you have is cause simply by the definition of the struct not being available in PlayBoard.c. For instance, if you only have
struct foo;
void foo(struct foo *foov) { ... }
without a definition of foo available, as in
struct foo { int a; ... }
then you won't be able to access the members of the structure (see "opaque type").
If I understand correctly and you want to change where theBoard points to, you need to define it as a pointer to pointer, not as pointer.
MoveSucc = putBoardSquare(&theBoard, getX, getY, nextTurn);
and change the parameter in putBoardSquare() to ** and when you set the pointer do it like (assuming x is a pointer):
*theBoard = x;