I have a structure like this :
typedef struct s_struct
{
float x1;
float y1;
float x2;
float y2;
} t_struct;
this is used to draw some stroke on my screen but I have a little problem, I want to change my X value when the right arrow is pressed but it segfaults, I think it's because I don't send properly my structure address...
This is how I do :
void draw_all(t_struct *param)
{
draw_horizon(param);
draw_verti(param);
}
void draw_horizon(t_struct *param)
{
param->x1 = param->x1 + param->C_Y;
param->y1 = param->y1 + param->C_X;
param->x2 = param->x2 + param->C_Y;
param->y2 = param->y2 + param->C_X;
param->y2 = param->y2 + param->C_X;
stroke(param);
}
And the function who is called when I press my right arrow :
int event(int keycode, t_struct *param)
{
if (keycode == 53)
{
printf("exit succes.\n");
exit(1);
}
if (keycode == 124)
{
printf("====\n");
printf("PRE C_X = %f\n", param->C_X);
param->C_X = param->C_X + 1;
printf("POST C_X = %f\n", param->C_X);
draw_all(¶m);
}
return (0);
}
My function draw_verti is the same but for verticals stroke...
The segfault is because I have a copy of my structure and I do not succeed to send the address ...
Thank you !
In the event function the variable param is a pointer. When you do ¶m you get a pointer to the pointer, which is of type t_struct **. This is not what the draw_all function expected.
Your compiler should be complaining about it, if you had proper prototypes.
Related
Does somebody know how to do send name of structure parameter as argument? I have code like this:
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points, name /*name of parameter*/)
{
printf("%lf",points.name);
}
And, for example, call of function as i see it:
bucketSort(point1,"dis");
I think You can't send variable name as parameter But. You can check it like below
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points,char *name /*name of parameter*/)
{
if(name[0] == 'd' ) printf("%lf",points.dis);
else if(name[0] == 'x') printf("%lf",points.x);
else if(name[0] == 'y') printf("%lf",points.y);
}
You can define an enum and store all possible names. Then you can use this enum as the parameter to your function.
typedef enum {
ENUM_X = 0,
ENUM_Y = 1,
ENUM_DIS = 2
} STRCT_PARAM_NAME;
typedef struct {
double x;
double y;
double dis;
} Point;
void bucketSort (Point * points, STRCT_PARAM_NAME name) {
switch (name) {
case ENUM_X: printf("%lf\n", points->x); break;
case ENUM_Y: printf("%lf\n", points->y); break;
case ENUM_DIS: printf("%lf\n", points->dis); break;
default: printf("Invalid\n"); break;
}
}
Now, you can call bucketSort like this:
bucketSort(points_obj, ENUM_X);
Im having trouble initialising structures (well doing everything actually, but structures first). The struct is first made in a header as follows
typedef enum cell
{
BLANK, RED, CYAN
} Cell;
#define NAMELEN 20
typedef struct player
{
char name[NAMELEN + NULL_SPACE];
Cell token;
unsigned score;
} Player;
void initFirstPlayer(Player * player);
void initSecondPlayer(Player * player, Cell token);
#endif
=======================================================================
and I tried to initialise it here
void initFirstPlayer(Player * player)
{
int randNo = rand() % 2;
if (randNo == 0) {
token = RED;
}
else() {
token = CYAN;
}
player ; p1 = {
"placeholder",
token,
0,
}
}
void initSecondPlayer(Player * player, Cell token)
{ }
What is the correct way to initialise this player struct?
I suspect this should work for you. Use a generic initPlayer function. Use that to allocate memory for the player and set the initial values. Be sure to also include a freePlayer function where you free() the player when you're done.
#include <stdlib.h>
#include <string.h>
Player* initPlayer()
{
Player* player = malloc(sizeof(Player));
int randNo = rand() % 2;
if (randNo == 0) {
player->token = RED;
}
else {
player->token = CYAN;
}
const char* initName = "placeholder";
strcpy(player->name, initName);
player->score = 0;
return player;
}
void freePlayer(Player* p)
{
free(p);
}
The way you'd use this would be like so:
int main()
{
Player* p1 = initPlayer();
Player* p2 = initPlayer();
play(p1, p2);
freePlayer(p1);
freePlayer(p2);
}
Assuming you have at least C99 support, so that compound literals and designated initializers are available to you, then you can use:
void initFirstPlayer(Player *player)
{
*player = (Player){ .token = rand() % 2 ? CYAN : RED,
.score = 0,
.name = "placeholder"
};
}
This does a structure assignment to the variable whose address is passed to the function. It compresses it all into one statement; you can split it out into several if you wish. This is an occasion where the ternary ? : operator is useful. You might prefer (rand() % 2) with the extra parentheses; I'd probably add them as often as I'd omit them.
The compound literal comes from (typename){ ...initializer for typename... }.
The designated initializers are the .member = value notations.
If you're stuck with C90 support, you have to work harder, perhaps creating a local variable with the correct information and then doing the structure assignment.
void initFirstPlayer(Player *player)
{
Player p1 = { "placeholder", rand() % 2 ? CYAN : RED, 0 };
*player = p1;
}
Now the onus is on you to list the initializers in the correct sequence.
Another way is to receive the player you want to inicialize as parameter:
void initPlayer(Player* player)
{
int randNo = rand() % 2;
if (randNo == 0) {
player->token = RED;
}
else {
player->token = CYAN;
}
const char* initName = "placeholder";
strcpy(player->name, initName);
player->score = 0;
}
int main() {
Player p1;
initPlayer(&p1);
}
You can have an array of players or allocate dinamically with malloc.
I'm having a strange behavior with the following simple ANSI C code. I have a pointer to a char inside a struct, and somehow, i have bad pointers, nulls and segfaults. Am i doing something stupid?
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAX_ENTITIES 10
typedef enum
{
COMPONENT_NONE = 0,
COMPONENT_DISPLACEMENT = 1 << 0,
COMPONENT_VELOCITY = 1 << 1,
COMPONENT_APPEARANCE = 1 << 2
} component_t;
typedef struct
{
float x;
float y;
} Displacement;
typedef struct
{
float x;
float y;
} Velocity;
typedef struct
{
char *name;
} Appearance;
typedef struct
{
int entities[MAX_ENTITIES];
Displacement displacement[MAX_ENTITIES];
Velocity velocity[MAX_ENTITIES];
Appearance appearance[MAX_ENTITIES];
} scene_t;
typedef struct
{
int active;
scene_t *current_scene;
} game_t;
unsigned int entity_create(scene_t *scene)
{
unsigned int entity;
for (entity = 0; entity < MAX_ENTITIES; ++entity) {
if (scene->entities[entity] == COMPONENT_NONE) {
printf("Entity created: %u\n", entity);
return entity;
}
}
printf("Error! No more entities left!\n");
return MAX_ENTITIES;
}
unsigned int scene_add_box(scene_t *scene, float x, float y, float vx, float vy)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_VELOCITY | COMPONENT_APPEARANCE;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->velocity[entity].x = vx;
scene->velocity[entity].y = vy;
scene->appearance[entity].name = "Box";
return entity;
}
unsigned int scene_add_tree(scene_t *scene, float x, float y)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_APPEARANCE;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->appearance[entity].name = "Tree";
return entity;
}
unsigned int scene_add_ghost(scene_t *scene, float x, float y, float vx, float vy)
{
unsigned int entity = entity_create(scene);
scene->entities[entity] = COMPONENT_DISPLACEMENT | COMPONENT_VELOCITY;
scene->displacement[entity].x = x;
scene->displacement[entity].y = y;
scene->velocity[entity].x = vx;
scene->velocity[entity].y = vy;
return entity;
}
void update_render(scene_t *scene)
{
const int mask = (COMPONENT_DISPLACEMENT | COMPONENT_APPEARANCE);
unsigned int entity;
Displacement *d;
Appearance *a;
for (entity = 0; entity < MAX_ENTITIES; ++entity) {
if ((scene->entities[entity] & mask) == mask) {
d = &(scene->displacement[entity]);
a = &(scene->appearance[entity]);
printf("%s at (%f, %f)\n", a->name, d->x, d->y);
}
}
}
void game_init(game_t *game)
{
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
game->active = 0;
scene_add_tree(game->current_scene, 5.0f, -3.2f);
scene_add_box(game->current_scene, 0.0f, 0.0f, 0.0f, 0.0f);
scene_add_ghost(game->current_scene, 10.0f, 4.0f, 0.0f, 0.0f);
}
void game_update(game_t *game)
{
update_render(game->current_scene);
}
int main(int argc, char **argv)
{
game_t game;
memset(&game, 0, sizeof(game));
game_init(&game);
while (game.active == 0) {
game_update(&game);
}
return 0;
}
In game_init, you are declaring a local variable of type scene_t. Once game_init ends, this variable no longer exists - you cannot use it correctly outside that function, but that's what you try to do when you access the scene inside your game_t variable.
If you want to create a scene_t which can be used outside of the function, you need to allocate the memory for it manually by using
scene_t* scene = malloc(sizeof(scene_t));
...and then working with it as a pointer instead.
You are saving a local address, when function goes out of scope "scene" will be destroyed.
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
You should instead allocate scene
scene_t* scene = malloc(sizeof(scene_t));
The problem is that you're not allocating a scene:
scene_t scene;
memset(&scene, 0, sizeof(scene));
game->current_scene = &scene;
the scene_t object here is on the stack and that memory will be reclaimed once you exit from the function. You should instead use
scene_t *pscene = malloc(sizeof(scene_t));
memset(pscene, 0, sizeof(scene));
game->current_scene = pscene;
this way the memory will be allocated from the heap, surviving the exit from the function.
You will need later to free this memory once done with the object.
You also don't assign a value to scene->appearance when you are creating a new ghost. When you then try and print the appearence later you'll get whatever the pointer happens to point to printed ou.
I must read and extract some values from string.
These values are coded like this:
k="11,3,1" v="140.3"
I have defined the codes and created struct with all field as well as a temp one where I store k and v. In fillFields proc I transfer values from temp struct to the right one (with the valid types).
It works but I have many fields and fillFields would need to have many if-conditions. Maybe someone could give me any hint how to write it smarter.
The simplified code now:
#define ASK "11,3,1"
#define BID "11,2,1"
#define CLOSE "3,1,1"
typedef struct tic {
float ask;
float bid;
float close;
}tic, *ticP;
typedef struct pElem {
char * k;
char * v;
}pElem, *pElemP;
void fillFields(ticP t, pElemP p)
{
if (strcmp( ASK, p->k)==0)
{
printf ("ASK %s\n", p->v);
t->ask = atof(p->v);
}
if (strcmp( BID, p->k)==0)
{
printf ("BID %s\n", p->v);
t->bid = atof(p->v);
}
if (strcmp( CLOSE, p->k)==0)
{
printf("CLOSE >>>%s<<<\n", p->v) ;
t->close = atof (p->v);
}
}
Rather than save the text value in pElem, save the converted values.
This creates an extra step in parsing k="11,3,1" v="140.3", to convert text to an enumerated type, but it's paid once. The fillFields() calls then run simpler. Assuming you have more ticP variables, it's a win.
typedef enum pElem_type {
pElem_None, pElem_ASK, pElem_BID, pElem_CLOSE, pElem_N
} pElem_type;
typedef struct pElem {
pElem_type type;
float value;
} pElem;
void fillFields(ticP t, const pElem *p) {
switch (p->type) {
case pElem_ASK:
printf("ASK %f\n", p->value);
t->ask = p->value;
break;
case pElem_BID:
printf("BID %f\n", p->value);
t->bid = p->value;
break;
case pElem_CLOSE:
printf("Close %f\n", p->value);
t->close = p->value;
break;
default:
printf("Error\n");
}
}
// Further simplifications possible
typedef struct tic {
float field[pElem_N];
}tic, *ticP;
static const char *FieldName[pElem_N] = {
"None", "ASK", "BID", "Close"
};
void fillFields(ticP t, const pElem *p) {
if (p->type < pElem_N) {
printf("%s %f\n", FieldName[p->type], p->value);
t->field[p->type] = p->value;
}
}
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;