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.
Related
#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;
}
LibRaw is a library for reading RAW files from digital photo cameras (CRW/CR2, NEF, RAF, DNG, MOS, KDC, DCR, etc.; virtually all RAW formats are supported).
I want to know how to use LibRaw to get the raw data of a Canon CR2 image.
typedef struct
{
ushort (*image)[4] ;
libraw_image_sizes_t sizes;
libraw_iparams_t idata;
libraw_lensinfo_t lens;
libraw_makernotes_t makernotes;
libraw_shootinginfo_t shootinginfo;
libraw_output_params_t params;
unsigned int progress_flags;
unsigned int process_warnings;
libraw_colordata_t color;
libraw_imgother_t other;
libraw_thumbnail_t thumbnail;
libraw_rawdata_t rawdata;
void *parent_class;
} libraw_data_t;
typedef struct
{
void *raw_alloc;
ushort *raw_image;
ushort (*color4_image)[4] ;
ushort (*color3_image)[3];
float *float_image;
float (*float3_image)[3];
float (*float4_image)[4];
short (*ph1_cblack)[2];//
short (*ph1_rblack)[2];//
libraw_iparams_t iparams;//
libraw_image_sizes_t sizes;//
libraw_internal_output_params_t ioparams;//
libraw_colordata_t color;//
} libraw_rawdata_t;
This is the data structure of RAW data, I don't know which structure the most primitive data is stored in.
I have already got the answer, now download it below, I hope to help those in need.
int i,ret,verbose = 0,output_thumbs = 0;
char outfn [1024],thumbfn [1024];
//Create object
LibRaw RawProcessor;
putenv((char *)"TZ = UTC+8");
//
#define P1 RawProcessor.imgdata.idata
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define T RawProcessor.imgdata.thumbnail
#define P2 RawProcessor.imgdata.other
#define OUT RawProcessor.imgdata.params
OUT.output_tiff = 0; //
OUT.no_auto_scale=1;//
OUT.no_auto_bright=1;//
OUT.output_bps=16;//16bit
OUT.output_color=0;//RAW
//openfile
if((ret = RawProcessor.open_file(szFile))!= LIBRAW_SUCCESS)
{
fprintf(stderr,"Can not open%s:%s\n",szFile,libraw_strerror(ret));
RawProcessor.recycle();
return FALSE;
}
//RAW size
int height=S.raw_height;
int width=S.raw_width;
//image info
memset(LinsnData.imgdata.make,0,64*sizeof(char));
memset(LinsnData.imgdata.model,0,64*sizeof(char));
memcpy(LinsnData.imgdata.make,P1.make,strlen(P1.make));
memcpy(LinsnData.imgdata.model,P1.model,strlen(P1.model));
LinsnData.imgdata.aperture=P2.aperture;
LinsnData.imgdata.iso_speed=P2.iso_speed;
LinsnData.imgdata.shutter=P2.shutter;
char timestamp[64]= {0};
tm* local = localtime(&P2.timestamp); //
strftime(LinsnData.imgdata.timestamp, 64, "%Y-%m-%d %H:%M:%S", local);
/***************************************************************************************************/
//
if((ret = RawProcessor.unpack())!= LIBRAW_SUCCESS)
{
fprintf(stderr,"Can not unpack_thumb%s:%s\n",szFile,libraw_strerror(ret));
//if(LIBRAW_FATAL_ERROR(ret))
goto end;
}
WORD *bmpData=RawProcessor.imgdata.rawdata.raw_image;
int nWidth = width/2;
int nHeight = height/2;
WORD *m_bmpDataR = new WORD[nWidth*nHeight];
WORD *m_bmpDataG = new WORD[nWidth*nHeight];
WORD *m_bmpDataB = new WORD[nWidth*nHeight];
//
for(int i=0;i<nHeight;i++)
{
for(int j=0;j<nWidth;j++)
{
m_bmpDataB[i*nWidth+j] = bmpData[i*nWidth*4+nWidth*2+j*2+1];
m_bmpDataG[i*nWidth+j] = ((bmpData[i*nWidth*4+nWidth*2+j*2]+bmpData[i*nWidth*4+j*2+1])>>1);
m_bmpDataR[i*nWidth+j] = bmpData[i*nWidth*4+j*2];
}
}
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.
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 */
}
Here is a struct in header-file:
typedef struct Missile {
int id;
Model *model;
Point3D coords;
int counter;
float speed;
float yaw;
float pitch;
float roll;
} Missile;
and here is code from C-file:
#define INIT_MISSILE_ARRAY_SIZE 4
/* An array to keep track of all missiles created (fired) */
static Missile *missiles[INIT_MISSILE_ARRAY_SIZE];
/* This keeps track of the array missiles' size */
int currentArraySize = INIT_MISSILE_ARRAY_SIZE;
int numOfMissiles = 0;
Missile *CreateMissile()
{
if (numOfMissiles < currentArraySize)
{
Missile *missile = malloc(sizeof(Missile));
missile->model = LoadModelPlus("rocket1.obj");
missile->counter = 0;
missile->speed = 0.00;
missile->yaw = 0.00;
missile->pitch = 0.00;
missile->roll = 0.00;
missile->id = numOfMissiles;
missiles[numOfMissiles] = missile;
numOfMissiles++;
printf("Missile created, numOfMissiles: %d\n", numOfMissiles);
return missile;
}
printf("Too many missiles fired already.\n");
return NULL;
}
void DeleteMissile(Missile *missile)
{
free(missile);
}
gives me this error: double free or corruption (fasttop): 0x000000000234f5d0
when the function DeleteMissile(Missile *missile) is called. I have tried replacing free(missile); with free(missiles[missile->id]);, which finds the (same) missile in the global array of missiles and calls free() on that one, and this gives me the same error. The function LoadModelPlus() uses malloc for the missile->model.
Can anyone see what I'm doing wrong?