Using MPI_Reduce in c - c

I am trying to write a program in c using the MPI library.
In my program I am solving TSP (but not with any special algorithm...).
My input parameters are int nCites, int xCoord[] and int yCoord[].
I am bundling them into Coordinates and using MPI_Bcast to make them available to all the threads.
My problem is this: after I've finished calculating the weight of all the paths in each thread, I want to reduce them into one single result, the best one. I've tried using MPI_Reduce, but something, and this is where I get confused, causes a segmentation fault (only in one of the threads, usually root).
This is the main code and structs:
typedef struct Coordinates_t {
int* x;
int* y;
int n;
} Coordinates;
typedef struct PathAndLength_t {
int* path;
int pathSize;
int length;
} PathAndLength;
void comparePaths(void* a, void* b, int* len, MPI_Datatype* dataType) {
...
}
int tsp_main(int nCites, int xCoord[], int yCoord[], int P[]){
int numOfProcs, rank;
if (MPI_Comm_size(MPI_COMM_WORLD, &numOfProcs))
throw "Error: MPI_Comm_size failed";
if (MPI_Comm_rank(MPI_COMM_WORLD, &rank))
throw "Error: MPI_Comm_rank failed";
Coordinates crds;
crds.x = xCoord;
crds.y = yCoord;
crds.n = nCites;
MPI_Datatype data;
createInDataType(&crds, &data);
if (MPI_Bcast(&crds, 1, data, 0, MPI_COMM_WORLD))
throw "Error: MPI_Comm_size failed";
...
PathAndLength* pal = (PathAndLength*)malloc(sizeof(PathAndLength));
pal->path = (int*)malloc(sizeof(int)*crds.n);
pal->length = min_length;
for (int i = 0; i < crds.n; ++i) {
(pal->path)[i] = min_path[i];
}
pal->pathSize = crds.n;
MPI_Datatype outDatatype;
MPI_Op op;
createOutDataType(pal, &outDatatype);
MPI_Op_create(&comparePaths, 1, &op);
PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength));
result->path = (int*)malloc(sizeof(int)*crds.n);
MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD);
...
return result->length;
}
And these are the createOutDataType and createInDataType I use in my code:
void createInDataType(Coordinates* indata, MPI_Datatype* message_type_ptr) {
// Build a derived datatype
int block_lengths[3];
MPI_Aint displacements[3];
MPI_Aint addresses[4];
MPI_Datatype typelist[3];
// First specify the types
typelist[0] = typelist[1] = typelist[2] = MPI_INT;
// Specify the number of elements of each type
block_lengths[0] = block_lengths[1] = indata->n;
block_lengths[2] = 1;
// Calculate the displacements of the members relative to indata
MPI_Address(indata, &addresses[0]);
MPI_Address(indata->x, &addresses[1]);
MPI_Address(indata->y, &addresses[2]);
MPI_Address(&indata->n, &addresses[3]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
displacements[2] = addresses[3] - addresses[0];
// Create the derived type
MPI_Type_struct(3, block_lengths, displacements, typelist, message_type_ptr);
// Commit it so that it can be used
MPI_Type_commit(message_type_ptr);
}
void createOutDataType(PathAndLength* outdata, MPI_Datatype* message_type_ptr) {
// Build a derived datatype
int block_lengths[2];
MPI_Aint displacements[2];
MPI_Aint addresses[3];
MPI_Datatype typelist[2];
// First specify the types
typelist[0] = MPI_INT;
typelist[1] = MPI_INT;
// Specify the number of elements of each type
block_lengths[0] = outdata->pathSize;
block_lengths[1] = 1;
// Calculate the displacements of the members relative to outdata
MPI_Address(outdata, &addresses[0]);
MPI_Address(outdata->path, &addresses[1]);
MPI_Address(&outdata->length, &addresses[2]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
// Create the derived type
MPI_Type_struct(2, block_lengths, displacements, typelist, message_type_ptr);
// Commit it so that it can be used
MPI_Type_commit(message_type_ptr);
}
Sorry for including so much code, but I couldn't decide what, if any, was irrelevant...
Thank you.

PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength));
result->path = (int*)malloc(sizeof(int)*crds.n);
MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD);
you are receiving crds.n*outDatatypes into result buffer of size sizeof(PathAndLength). You seem to have design flaw.

Related

structure initialization for xh711 issue

I am building a program for Xh711 on esp32. I have defined a a struct and i am trying to initialize it. I am getting the next error.
could not convert '{GPIO_NUM_18, GPIO_NUM_19, 0, 1, 1, GAIN64, 0, -1,
storm->ad_str_t::smoothed, storm->ad_str_t::sampling,
storm->ad_str_t::timerHandle}' from '' to 'ad_xh711_handle_t'
void str_init_Xh711(ad_str_t *storm){
printf("Starting xh711...\n");
ad_xh711_handle_t xh711={
.dout= GPIO_NUM_18,
.scl= GPIO_NUM_19,
.offset = 0,
.calibrationFactor = 1,//NULL,
.conversionFactor=1,
.gainValue= Gain::GAIN64,
.rawData =0,//NULL,
.value = -1,
.smoothed =storm->smoothed,
.sampling =storm->sampling,
.timerHandle = storm->timerHandle
};
xh711_init(&xh711,Gain::GAIN64);
}
typedef struct {
gpio_num_t dout;
gpio_num_t scl;
int32_t offset = 0;
double calibrationFactor;
double conversionFactor=1;
Gain gainValue;
int32_t rawData;
double value = -1;
bool smoothed;
uint8_t sampling;
esp_timer_handle_t timerHandle;
}ad_xh711_handle_t;
default values in typedef can not work and have to be removed

I need help understanding how the input for a SHA-256 function is generated for the following equation? (Equation and C code are in the body)

I have the following equation:
c = SHA-256(Q, K(i,0), K(i,1), ..., K(i,k-1), h(i,0), h(i,2), …, h(i,k-1)) mod q
and the input values:
k1 = 26629345189088775121568614899346754418407425670282456807855951340359412290983328619915824219380693572974892394721160483070683405782674706936012623642495432802102362447142115308612541414114873855847753397157927768798152813362950360882910824404185543828373250626406490554333742647857888385433264463011767352745302500858815513643866365318023238515892185480255556180043825147988975721600405726006369401295379371876907754637420274357720509199471355271282430522552899184689005974089671519735287643350136311957077142232015824857171723946921408511190415079318863767715152598154929621042345763672724819984668317829111226813269324209780774070525891398264036597683937747328345947347006730334861476983902927279277507787575185292041114946942224086350752748835970487839469028361776247769179401048268608771986025484163476920237083790508471442085270390251953238194531355009119632874716585236991029452845316964868506545640819423936068521643730339939001494181525262110553268664909094721286556270076920384038188879583376531394141804457267751604148270282108259247832356847127150570530180974823739916755872393975601311483606457834350419278739508231896982519584456058749640647320286547658303183817323255694318300072593537885262339027581180645983887817698
c1 = 734543921447752682860963741453271489254669074261452175542578379592174452839224593393703391880811403700322170448354231579471856009386877575200881769436034155106097824226934309597824740339277501680651938212698873436444596418869933750778491012116425109317627750740344709043308724472066983029401792501819476640899479142794577184544149738356048994164406614202147840757079571415055902412124590217393369133432772089352174603222770484553027183660348288914566202679602860020529368818277755524985768471918648089084661467706102641509311739166386367723205389105075633496812514886817188079551423050513374871126883407747450151616425645668060446634154143217625159743590285484972355255238869505937349605491386760180995206011578729743013682469984157163036398663818798440392573212425655089539747818287610595634083808227422158212010691046377845002010543256975163259924983922679163639111554660321472736871186841262131253852347056806886358462294157243037821998920179238526878715076500283110919518891844033357565717323278006862495035476503209297028628017256090700319869519223575598336559377555360887798178911373373442813544654297399825285204120194023356602791705863456979459155048848360183764309689023948392715748473787550542570249723129662907674477638155
k2 = 724306184502452816914739636531581573398224256279083526602303340064699627757014049622722889151635945057642978593144466015150186765749429007022463174881008385163668958538291569232830916960267390644040463451545083453683137865954156414068207252834671150050230255180288936398706033028362268184070023700566186274532263796291894927127975670890282152122433688726389989701586888271064122385183397877731811664221480084098496216725545564395282084139240651524033726896508389071330557491953584326868064837709120578687992214838787904024645756660442212940703778909386591826708938137607549444028276378620609318898454821291364028468209002629435384439334275676426619969415671283814148831406419950854501712607728573652310442073075148545691196141281959772421121788160611597927035716264228366448773758536392715750804355693616056767759733884275733248674940223335744206764349613456780149740515230706213960637774640903260073440687688080738513266487388466874967097580183317352352528411749422080000701364398585637123229143584857790913010601582400680315552121860435131370132521955498539709027515119810680201720176721371774526144957969963795913966561771154554007108017412796782369595818252395204162594183872855697712261245935201585493709477582706545110177215821
c2 = 960221739782881106555520690425010021039585697375816813285014948220116582496349414446142162406509753922593294847577826271344763374425662278801507623833820453216455460185550582399315410348641894949519588859323455000172448782529224481484918103318720863771957070639951336008985481947370670335767955378467353564540035526375700200523121630039790665126285801382016391303110496204411872885996357354686792750135457983293270066969146882695818607312528809187016517329593195740668810983171380331914401335171387213965098493731439319476275893571797762861205757895023884585731945877491242801012769926227492771321066531612791066707440624147290380155429468669494769813751862398804945260809411280200398348147795410174888383205691492187198062430278675590774396397281939708919378301067496400267178657524850286567847615206797163142422024404626731519858652912211514019423275106047908769463693293757782776222110798002284650689612049828032376408961151193626321252723460150586589089554245715379071888777564666860949848005686192812909337601685707804165804391349748040122892709856331573634788924909137912414238191925947288844267171022696511723826646623945630158106755346844078558126606952907847470260872591076346814485117343087981545828213509231993289085481079
k3 = 799737129063619060980186531810540973616519619203110282518893207950107032146263649853584297641702236374647934368387645168243333744620375086421375217304328649047889464104572220385314337647812195946053145934972855486518217344467748649395041364170018881222850516218463457694043690070610237878709202140505622325856394862233739651070594401354996501462264916343662664663750294863619369110306031216985620216531032240789225780217360237093973705672203318815400457665497655830930368916738077012489344585922166324933843097891531710057912227460681611764729991272097760822195680648333439781758314525469445823330621961732379024591923851064623673967629656983337270502231192038213311591591852092660431136466541584566799881928515491081391784205577911778860376258928442453391179453117517770706569098118773667261672847676362128880181433677057980663416494282366577752013642111948903060977493035948850819640995719344234551655987738805766061084497694525597901163154991914475628938146786417045064604883915272654028399820284008006221014104129294794152326436558376269116528596225864413103050355700341444198858362383935631584183877470020797558532096820474349736907328329150651341592335719339672129460954391715475554119213934697947889992942331391289874986722644
c3 = 931797555253192482989295432719099701351725859216950729469328137669368124524037275640969388386294393863186533642116864964902964176998076338604990103121527015467339604839513187289532824213203400067099767775735388546384888382618864386446365393297408865199811109011533921601107559078837930497335475413751998769666310700512719654775817073566628105606295367733582808225698806269677813440049932235996765125355716503296196997654429151489480851485231905421974216329262367438935656139424158432987182719342429331558088121739762373105585510925738731762080307813016673130073259117866068045713316807346582009739697941333093783066128418383088176394567764937369175627648077187727514232345675336885442770669792084018689606391841348624952897664676154759047521966624373811267917078799812617422111420583245858467168273670917230712601889749733664525919016162074632146206866827081484263360545715204692637956990824806452529593025178450715208783670127033609657051746563255216566806770015789200150070927993530100790362032729177252769026244410363639800134084155592002493615681452472126869694192600950243247202905294879485713700522046811740291436627119252689670273539661939802646693394326061378651878486620673271447923987682207439505838886221198451291168850926
Q = 409769201286042520263200333546996463643161763414612173001850880
c = 65327730069392099560592212062758966359893028444080519192014624164847259261454
q = 2**256 - 189
The trouble I am having is understanding how the input string for the SHA-256 function is generated by combining all the inputs. The only cue I have is a bunch of following C code that doesn't make much sense to me because I haven't done C programming in a while.
The C code:
void Crypto_cp_proof_challenge(struct hash *challenge_out,
struct encryption_rep encryption,
struct encryption_rep commitment,
struct hash base_hash)
{
SHA2_CTX context;
//Serialize the base hash
uint8_t *base_serial = Serialize_reserve_write_hash(base_hash);
//Generate the challenge
SHA256Init(&context);
SHA256Update(&context, base_serial, SHA256_DIGEST_LENGTH);
Crypto_hash_update_bignum_p(&context, encryption.nonce_encoding);
Crypto_hash_update_bignum_p(&context, encryption.message_encoding);
Crypto_hash_update_bignum_p(&context, commitment.nonce_encoding);
Crypto_hash_update_bignum_p(&context, commitment.message_encoding);
Crypto_hash_final(challenge_out, &context);
}
void Crypto_hash_update_bignum_p(SHA2_CTX *context, mpz_t num)
{
uint8_t *serialized_buffer = Serialize_reserve_write_bignum(num);
SHA256Update(context, serialized_buffer, 4096 / 8);
free(serialized_buffer);
}
uint8_t *Serialize_reserve_write_bignum(mpz_t in)
{
struct serialize_state state = {.status = SERIALIZE_STATE_RESERVING,
.len = 0,
.offset = 0,
.buf = NULL};
Serialize_reserve_uint4096(&state, NULL);
Serialize_allocate(&state);
Serialize_write_uint4096(&state, in);
assert(state.len == 512);
return state.buf;
}
void Serialize_write_uint4096(struct serialize_state *state, const mpz_t data)
{
Serialize_write_uint64_ts(state, data, UINT4096_WORD_COUNT);
}
void Serialize_write_uint64_ts(struct serialize_state *state, const mpz_t data,
int ct)
{
uint64_t *tmp = NULL;
bignum_status export_status = export_to_64_t(data, ct, &tmp);
if (export_status == BIGNUM_SUCCESS)
{
if (tmp != NULL)
{
for (uint32_t i = 0; i < ct; i++)
{
Serialize_write_uint64(state, &tmp[i]);
}
free(tmp);
}
else
{
DEBUG_PRINT(("\nSerialize_write_uint64_ts: tmp is null - FAILED!\n"));
}
}
else
{
DEBUG_PRINT(("\nSerialize_write_uint64_ts: export_to_64_t - FAILED!\n"));
state->status = export_status == BIGNUM_IO_ERROR
? SERIALIZE_STATE_IO_ERROR
: SERIALIZE_STATE_INSUFFICIENT_MEMORY;
}
}
I have to replicate the function in Python. I would be really thankful if somebody can help me understand the flow of data in the C code, especially how the inputs are combined into a single string that is passed to the SHA-256 function.
Thanks.

CPLEX MIP current node LP relaxation

During a MIP optimization with CPLEX C APIs is it possible to retrieve the linear relaxation (dual variables, reduced costs, etc ...) of the current node (i.e. every n nodes)?
I've registered a callback function (CPXsetsolvecallbackfunc) in order to be notified each time a new node is available. In the callback I use CPXgetcallbackinfo to retrieve the node information and CPXgetcallbacknodelp to retrieve the linear relaxation but unfortunately the procedure CPXsolution returns that no solution exists and the MIP optimization exits.
Here is a sample code realized starting from an IBM example where environment and problem are assumed to be properly initialized.
struct noderange {
int startnode;
int endnode;
};
typedef struct noderange NODERANGE;
NODERANGE nodeswritten;
nodeswritten.startnode = -1;
nodeswritten.endnode = 2100000000;
status = CPXsetsolvecallbackfunc(environment, usersolve, &nodeswritten);
if(status) {goto TERMINATE;}
status = CPXmipopt(environment, problem);
if(status) {goto TERMINATE;}
where the usersolve procedure is
static int CPXPUBLIC usersolve(CPXCENVptr env, void *cbdata, int wherefrom, void *cbhandle, int *useraction_p) {
int status = 0;
int nodecount;
static int count = 0;
CPXLPptr nodelp;
NODERANGE *nodeswritten;
*useraction_p = CPX_CALLBACK_DEFAULT;
nodeswritten = (NODERANGE *)cbhandle;
/* Find out what node is being processed */
status = CPXgetcallbackinfo(env, cbdata, wherefrom, CPX_CALLBACK_INFO_NODE_COUNT, &nodecount);
if (status) goto TERMINATE;
if (nodecount >= nodeswritten->startnode && nodecount <= nodeswritten->endnode) {
/* Get pointer to LP subproblem, then write a SAV file. */
status = CPXgetcallbacknodelp(env, cbdata, wherefrom, &nodelp);
if (status) goto TERMINATE;
int rows = CPXgetnumcols(env, nodelp);
int cols = CPXgetnumrows(env, nodelp);
int lpstat;
double objval;
double* x = (double*)malloc(sizeof(double) * CPXgetnumcols(env, nodelp));
double* dj = (double*)malloc(sizeof(double) * CPXgetnumcols(env, nodelp));
double* pi = (double*)malloc(sizeof(double) * CPXgetnumrows(env, nodelp));
double* slack = (double*)malloc(sizeof(double) * CPXgetnumrows(env, nodelp));
status = CPXsolution(env, nodelp, &lpstat, &objval, x, pi, slack, dj);
printf("Solutionstatus = %d\n", lpstat);
if (status) { goto TERMINATE; } // <--- HERE it returns no solution exists
free(x);
free(dj);
free(pi);
free(slack);
printf("[%d]\trows = %d cols = %d\t sol stat = %d\t z = %f\n", nodecount, rows, cols, lpstat, objval);
if (nodecount == nodeswritten->endnode) status = 1;
count++;
}
TERMINATE:
return (status);
}
I found out the problem, the callback is called before the subproblem has been solved so CPXsolution returns that no solution exists.

Memory corruption when implementing a Pure Data external using C

I am currently trying to implement an external for Pure Data using C. I've not been using C for a while, and I have a memory corruption problem. I don't know what to do, so I'm asking for your help.
Here is the code. Please remember that it is a C code for Pure Data.
t_int *myfft_tilde_perform(t_int *w) {
t_myfft_tilde *fft = (t_myfft_tilde *)w[1];
t_float *in = (t_float *)w[2];
t_float *out = (t_float *)w[3];
int n = (int)w[4];
int i;
for(i=0; i<n; i++)
{
fft->bigbuffer[fft->nextindex] = in[i];
fft->nextindex = (fft->nextindex+1)%TAILLE;
}
if (!fft->isfull && fft->nextindex==0)
{
fft->isfull=1;
}
if (fft->isfull)
{
for(i=0; i<TAILLE; i++)
{
fft->bigbuffercpy[i] = fft->window[i] * fft->bigbuffer[i];
}
rdft(TAILLE, 1, fft->bigbuffercpy, fft->bitshuffle, fft->weighting);
if (fft->nextindex==0)
{
i=(TAILLE-1)-64;
}
else
{
i=fft->nextindex-64;
}
int j;
for(j=0; j<64; j++)
{
out[j] = fft->bigbuffercpy[i+j];
}
}
return (w+5);
}
void myfft_tilde_dsp(t_myfft_tilde *x, t_signal **sp) {
dsp_add(myfft_tilde_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n);
}
void myfft_tilde_free(t_myfft_tilde *x) {
if (x->bitshuffle)
freebytes(x->bitshuffle, TAILLE*2*sizeof(int));
if (x->weighting)
freebytes(x->weighting, TAILLE*2*sizeof(float));
if (x->window)
freebytes(x->window, TAILLE*sizeof(float));
if (x->bigbuffer)
freebytes(x->bigbuffer, TAILLE*sizeof(float));
if (x->bigbuffercpy)
freebytes(x->bigbuffercpy, TAILLE*sizeof(float));
}
void *myfft_tilde_new(void) {
t_myfft_tilde *fft = (t_myfft_tilde *)pd_new(myfft_tilde_class);
fft->x_out = outlet_new(&fft->x_obj, &s_signal);
fft->bitshuffle = (int *)calloc(TAILLE*2, sizeof(int));
fft->weighting = (float *)calloc(TAILLE*2, sizeof(float));
fft->window = (float *)calloc(TAILLE, sizeof(float));
fft->bigbuffer = (float *)calloc(TAILLE, sizeof(float));
fft->bigbuffercpy = (float *)calloc(TAILLE, sizeof(float));
int i;
for(i=0; i<TAILLE; i++)
{
fft->window[i] = 0.54 - 0.46*cos(TWOPI*i/TAILLE);
}
fft->nextindex=0;
fft->isfull=0;
init_rdft(TAILLE*2, fft->bitshuffle, fft->weighting);
return (void *)fft;
}
void myfft_tilde_setup(void) {
myfft_tilde_class = class_new(gensym("myfft~"),
(t_newmethod)myfft_tilde_new,
(t_method)myfft_tilde_free,
0, sizeof(t_myfft_tilde),
CLASS_DEFAULT, A_GIMME, 0);
CLASS_MAINSIGNALIN(myfft_tilde_class, t_myfft_tilde, f);
class_addmethod(myfft_tilde_class, (t_method)myfft_tilde_dsp,
gensym("dsp"), 0);
}
The functions that you don't know are functions that have been given to me. The memory corruption error occurs this way : I compile the code using a given makefile, then I try to run a given Pure Data file using the resulting pd_linux file in my console, and I immediately get this message in the console :
*** Error in `puredata': malloc(): memory corruption: 0x084f4570 ***
Pd: signal 6
I tried even to remove all the calloc I've done, but the error still occurs...
you are using class_new() wrongly.
it's arguments are:
name
constructor
destructor
size of the member-data struct
flags
arg-specification for the constructor
a 0 (terminator)
you have swapped size and flags, giving an effective size of 0 bytes. pd_new() will then allocate 0 (zero, naught) bytes for your fft-struct, which leads to a memory corruption once you access the struct members (as you do in the next line).
apart from that: please always use t_sample instead of t_float (or float!!) for sample values.
always use t_float instead of float for message numbers.

Segfault with pointer to char inside struct, ANSI C code

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.

Resources