Welcome! Log In Create A New Profile

Advanced

Coding: Dynamically Defined Variables

Posted by LordAshes 
Coding: Dynamically Defined Variables
April 27, 2010 02:57PM
Here is a simplified example of what I want to do but can't seem to get it working right...

// Object Structure

typedef sturct
{
int x;
int y;
void *image_data;
} ObjectType;

// Static Image Structure

typedef struct
{
int width;
int height;
} StaticImageType;

// Animated Image Structure

typedef structure
{
int width;
int height;
int tile_width;
int tile_height;
int min_frame;
int current_frame;
int max_frame;
} AnimatedImageType;

// Create 100 Objects

ObjectType Objs[100];

// Initialization Functions

void Init_Static_Object(int id, int width, int height)
{
StaticImageType *tempData = malloc(sizeof(StaticImageType));
Objs[id].width = width;
Objs[id].height = height;
Objs[id].image_data = tempData;
}

void Init_Static_Object(int id, int width, int height)
{
AnimatedImageType *tempData = malloc(sizeof(AnimatedImageType));
Objs[id].width = width;
Objs[id].height = height;
Objs[id].image_data = tempData;
}


So basically you have one array of objects which all share common attributes like x position and y position. However, depending on the type of object each element in the object array can have the image_data attribute point to either a static image data structure or a animated image data structure...this decision is made dunamically during runtime. Ideally you should then be able to access the image_data attributes using something like Objs[0].imdage_data->width

The problem seems to be what type to make the initial image_data variable in the ObjectType structure. Someone previously suggested void but I can't seem to make it work.
Re: Coding: Dynamically Defined Variables
April 27, 2010 06:35PM
// Object Structure
enum ObjType { OT_Static, OT_Anim };

typedef struct {
int x, y;
enum ObjType type;
void *image_data;
} ObjectType;

typedef struct {
int width;
int height;
} StaticImageType;

typedef structure {
int width, height;
int tile_width, tile_height;
int min_frame, current_frame, max_frame;
} AnimatedImageType;

// Create 100 Objects
ObjectType Objs[100];

// Initialization Functions
void Init_Static_Object(int id, int width, int height)
{
StaticImageType *tempData = malloc(sizeof(StaticImageType));
Objs[id].width = width;
Objs[id].height = height;
Objs[id].image_data = tempData;
}

void Init_Static_Object(int id, int width, int height)
{
StaticImageType *tempData = malloc(sizeof(StaticImageType));
tempData->width = width;
tempData->height = height;
Objs[id].type = OT_Static;
Objs[id].image_data = (void*)tempData;
}
void Init_Anim_Object(int id, int width, int height)
{
AnimatedImageType *tempData = malloc(sizeof(AnimatedImageType));
tempData->width = width;
tempData->height = height;
Objs[id].type = OT_Anim;
Objs[id].image_data = (void*)tempData;
}

void Draw_Object(int id)
{
  if (Objs[id].type == OT_Static)
  {
    StaticImageType *tempData = (StaticImageType*)Objs[id].image_data;
    //Do drawing static
  }else if (Objs[id].type == OT_Anim)
  {
    AnimatedImageType *tempData = (AnimatedImageType*)Objs[id].image_data;
    //Do drawing with animation
  }
}
Re: Coding: Dynamically Defined Variables
April 28, 2010 05:26AM
Besides the addition of the Static and Non-Static flag...which is something I would obviously have (but did not include in the example)...the only change seems to be that you did a cast to (void*)...Thanks...I will check if that was my problem.
Re: Coding: Dynamically Defined Variables
April 28, 2010 05:49AM
Okay...so now the code is:

#include 
#include 

// Object Structure

typedef struct {
  int x, y;
  void *image_data;
} ObjectType;

typedef struct {
  int width;
  int height;
} StaticImageType;

typedef struct {
  int width, height;
  int tile_width, tile_height;
  int min_frame, current_frame, max_frame;
} AnimatedImageType;

// Create 100 Objects
ObjectType Objs[100];

// Initialization Functions
void Init_Static_Object(int id, int width, int height)
{
  StaticImageType *tempData = malloc(sizeof(StaticImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].image_data = (void*)tempData;
}

void Init_Anim_Object(int id, int width, int height)
{
  AnimatedImageType *tempData = malloc(sizeof(AnimatedImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].image_data = (void*)tempData;
}

int main()
{
  
  Init_Static_Object(0,64,64);
  Init_Anim_Object(1,64,64);
  
  printf("Object 0: (%d,%d)->(%d,%d)",Objs[0].x,Objs[0].y,Objs[0].image_data->width,Objs[0].image_data->height);
  printf("Object 1: (%d,%d)->(%d,%d)",Objs[1].x,Objs[1].y,Objs[1].image_data->width,Objs[1].image_data->height);
  
  return 0;
  
}

But this still generates errors:

main.c:48 warning: dereferencing 'void *' pointer
main.c:48 error: request for member 'width' in something not a structure or union
main.c:48 warning: dereferencing 'void *' pointer
main.c:48 error: request for member 'height' in something not a structure or union
main.c:49 warning: dereferencing 'void *' pointer
main.c:49 error: request for member 'width' in something not a structure or union
main.c:49 warning: dereferencing 'void *' pointer
main.c:49 error: request for member 'height' in something not a structure or union

To me this sounds like that although I change the image_data variable to point to one of the structures, the variable does not know what structure it is pointing at and thus it does not allow you to use the ->width and ->height reference. I am guessing if I read the memory at the image_data location I would find my values but I want to be able to use the -> reference so that I can easily refer to the variables in the strcuture in my code.

Anyone have some ideas?
Re: Coding: Dynamically Defined Variables
April 29, 2010 10:18PM
You have to cast malloc's as it is defined as a void* i.e.

StaticImageType *tempData = (StaticImageType*)malloc(sizeof(StaticImageType));
AnimatedImageType *tempData =(AnimatedImageType*)malloc(sizeof(AnimatedImageType));
Re: Coding: Dynamically Defined Variables
April 30, 2010 05:00AM
Doh! I am an idiot...of course...I have to cast it during the malloc step.

I should have know that...I even have some code for a Linked List that does the same thing.

Thanks...I will try that and hopefully that will solve my problem.
Re: Coding: Dynamically Defined Variables
April 30, 2010 05:42AM
#include 
#include 

// Object Structure

typedef struct {
  int x, y;
  void *image_data;
} ObjectType;

typedef struct {
  int width;
  int height;
} StaticImageType;

typedef struct {
  int width, height;
  int tile_width, tile_height;
  int min_frame, current_frame, max_frame;
} AnimatedImageType;

// Create 100 Objects
ObjectType Objs[100];

// Initialization Functions
void Init_Static_Object(int id, int width, int height)
{
  StaticImageType *tempData = (StaticImageType *) malloc(sizeof(StaticImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].image_data = (StaticImageType *)tempData;
}

void Init_Anim_Object(int id, int width, int height)
{
  AnimatedImageType *tempData = (AnimatedImageType *) malloc(sizeof(AnimatedImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].image_data = (AnimatedImageType *)tempData;
}

int main()
{
  
  Init_Static_Object(0,64,64);
  Init_Anim_Object(1,64,64);
  
  printf("Object 0: (%d,%d)->(%d,%d)",Objs[0].x,Objs[0].y,Objs[0].image_data->width,Objs[0].image_data->height);
  printf("Object 1: (%d,%d)->(%d,%d)",Objs[1].x,Objs[1].y,Objs[1].image_data->width,Objs[1].image_data->height);
  
  return 0;
  
}

I added the type cast into the malloc but that did not change things. So I tried to also also add it into the actual assignment but no matter what I do I keep getting:

main.c:48 warning: dereferencing 'void *' pointer
main.c:48 error: request for member 'width' in something not a structure or union
main.c:48 warning: dereferencing 'void *' pointer
main.c:48 error: request for member 'height' in something not a structure or union
main.c:49 warning: dereferencing 'void *' pointer
main.c:49 error: request for member 'width' in something not a structure or union
main.c:49 warning: dereferencing 'void *' pointer
main.c:49 error: request for member 'height' in something not a structure or union

I am casing the type correctly in the assignment statement?

I feel I am so close but I just need that last inch of help.
Re: Coding: Dynamically Defined Variables
April 30, 2010 06:05AM
why are you casting Objs[id].image_data = (StaticImageType *)tempData; that's a void* and should be

Objs[id].image_data = (void*)tempData;
Re: Coding: Dynamically Defined Variables
April 30, 2010 02:09PM
The whole reason for having the initial variable (i.e. the image_data pointer) be type void (or pointer to void) is because the structure that it will point to is not known at design-time.

Someone on this forum previously indicated that I should use type void for this type of situation.

However, the problem is that in the end I need to tell the pointer that it is no longer pointing at void but at one of the structures so that references like Objs[0].image_data->width will work.

I believe I have no problem making the pointer point at the structure but it is not recognizing at what it is pointing. So, I am guessing, if I read the memory values at the address pointed to by the pointer, I would get my structure data but that does not allow me to reference the structure data by the variable names.

I will try changing my cast to void* instead but my guess it that will not work either...but I will give it a try...and thanks for your advice in any case.
Re: Coding: Dynamically Defined Variables
April 30, 2010 06:58PM
Why don't you declare void *image_data; as StaticImageType* image_data if that's what it is? void* is only really used when you want the flexibility of passing in multiple or unknown data types and casting them back later.

Also is image_data supposed to hold the image data? Or is it a pointer to the StaticImageType struct? You're using it as a pointer to the StaticImageType struct. If it's just a pointer to this struct the following code would be be better. If it's meant to hold image data then what you think you're doing is completely wrong :{


typedef struct {
  int width;
  int height;
} StaticImageType;

typedef struct {
  int x, y;
  StaticImageType* image_data;
} ObjectType;



Re: Coding: Dynamically Defined Variables
May 05, 2010 02:27AM
With all due respect, I know you are just trying to help, but I believe I answered this in this thread above.

The reason why this is not possible is because the structure that image_data points to is not known at design time. In the simplified example above, it can point to either the startic or dynamic image structure. In my real code it can point to one of a hundred different structures. The decision as to which structure it points to is made at runtime.

I am fairly sure I have the pointer address correct (i.e. using memory commands I could probably read the structure data) but I would like it to recognize the structure so I can use references like objs[0].image_data->width.

This means the design time type needs to be generic (i.e. void) but at run-time this needs to be changed to one of the structure types.

(typing via PPC)
Re: Coding: Dynamically Defined Variables
May 05, 2010 04:43AM
Quote
LordAshes
With all due respect, I know you are just trying to help, but I believe I answered this in this thread above.

The reason why this is not possible is because the structure that image_data points to is not known at design time. In the simplified example above, it can point to either the startic or dynamic image structure. In my real code it can point to one of a hundred different structures. The decision as to which structure it points to is made at runtime.

I am fairly sure I have the pointer address correct (i.e. using memory commands I could probably read the structure data) but I would like it to recognize the structure so I can use references like objs[0].image_data->width.

This means the design time type needs to be generic (i.e. void) but at run-time this needs to be changed to one of the structure types.

(typing via PPC)

Sorry I missed that part.

Sounds like a hard way of doing it. Does you're code need to be strict C, this type of problem is exactly why C++ was created. You can use polymorphism and derive from a base class, much easier than casting voids and adding checks to see what the actual data type is.



Edited 1 time(s). Last edit at 05/05/2010 04:44AM by scanff.
Re: Coding: Dynamically Defined Variables
May 05, 2010 07:14AM
Completely off the top of my head, might have typos/stupid mistakes:
#include 
#include 

#define IMAGE_TYPE_STATIC 0
#define IMAGE_TYPE_ANIMATED 1

typedef struct {
  int width;
  int height;
  int type;
  // these fields are only valid if type==IMAGE_TYPE_ANIMATED
  int tile_width;
  int tile_height;
  int min_frame;
  int current_frame;
  int max_frame;
} ImageType;

// Object Structure

typedef struct {
  int x, y;
  ImageType *image_data;
} ObjectType;

// Create 100 Objects
ObjectType Objs[100];

// Initialization Functions
void Init_Static_Object(int id, int width, int height)
{
  ImageType *tempData = (ImageType *)malloc(sizeof(ImageType));
  tempData->width = width;
  tempData->height = height;
  tempData->type = IMAGE_TYPE_STATIC;
  Objs[id].image_data = tempData;
}

void Init_Anim_Object(int id, int width, int height)
{
  ImageType *tempData = (ImageType *)malloc(sizeof(ImageType));
  tempData->width = width;
  tempData->height = height;
  tempData->type = IMAGE_TYPE_ANIMATED;
  // set the other fields?
  Objs[id].image_data = tempData;
}

int main()
{
  
  Init_Static_Object(0,64,64);
  Init_Anim_Object(1,64,64);
  
  printf("Object 0: (%d,%d)->(%d,%d)",Objs[0].x,Objs[0].y,Objs[0].image_data->width,Objs[0].image_data->height);
  printf("Object 1: (%d,%d)->(%d,%d)",Objs[1].x,Objs[1].y,Objs[1].image_data->width,Objs[1].image_data->height);
  
  return 0;
  
}
Takes a bit more memory, but this is probably the simplest way unless you want to move the type field into ObjectType and make image_data a union.
Re: Coding: Dynamically Defined Variables
May 05, 2010 05:04PM
Quote
scanff
Sorry I missed that part. Sounds like a hard way of doing it. Does you're code need to be strict C, this type of problem is exactly why C++ was created. You can use polymorphism and derive from a base class, much easier than casting voids and adding checks to see what the actual data type is.

The reason why I need to do it similar to the way indicated above is because the original code was written by someone else and only a part of the code can be modified. Basically the code for the whole project is contained in 2 main file...one is available at design time and the other other is created dynamically. Due to the component that is generated dynamically I am limited to how I can approach the solution.
Re: Coding: Dynamically Defined Variables
May 05, 2010 05:09PM
Quote
tueidj
Completely off the top of my head, might have typos/stupid mistakes:
{Code removed to reduce space}
Takes a bit more memory, but this is probably the simplest way unless you want to move the type field into ObjectType and make image_data a union.

Thanks for the input but as I have explained, this is a similified version of my actual correct. The sample uses only 2 structures (Static Image and Animated Image) but my actual code can point to one of many (maybe hundreds) of sturctures. This would mean that the object definition would then be massive just to accomodate all the possible structures.
Re: Coding: Dynamically Defined Variables
May 05, 2010 08:05PM
Well you need to at least give an accurate example if you want people to improve it. Let's try again.
#include 
#include 

// Object Structure

#define OBJECT_TYPE_STATIC_IMAGE 0
#define OBJECT_TYPE_ANIMATED_IMAGE 1
// more defines for other object types go here

typedef struct {
  int x, y;
  int type;
  union {
    StaticImageType *StaticImageData;
    AnimatedImageType *AnimatedImageData;
    // other type pointers go here
  };
} ObjectType;

typedef struct {
  int width;
  int height;
} StaticImageType;

typedef struct {
  int width, height;
  int tile_width, tile_height;
  int min_frame, current_frame, max_frame;
} AnimatedImageType;

// Create 100 Objects
ObjectType Objs[100];

// Initialization Functions
void Init_Static_Object(int id, int width, int height)
{
  StaticImageType *tempData = (StaticImageType *)malloc(sizeof(StaticImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].type = OBJECT_TYPE_STATIC_IMAGE;
  Objs[id].StaticImageData = tempData;
}

void Init_Anim_Object(int id, int width, int height)
{
  AnimatedImageType *tempData = (AnimatedImageType *)malloc(sizeof(AnimatedImageType));
  tempData->width = width;
  tempData->height = height;
  Objs[id].type = OBJECT_TYPE_ANIMATED_IMAGE;
  Objs[id].AnimatedImageData = tempData;
}

int main()
{
  int i;
  Init_Static_Object(0,64,64);
  Init_Anim_Object(1,64,64);
  
  for (i=0;i<2;i++) {
    switch (Objs.type) {
      case OBJECT_TYPE_STATIC_IMAGE:
          printf("Object %d: (%d,%d)->(%d,%d)\n", i,Objs.x,Objs.y,Objs.StaticImageData->width,Objs.StaticImageData->height);
          break;
      case OBJECT_TYPE_ANIMATED_IMAGE:
          printf("Object %d: (%d,%d)->(%d,%d)\n", i,Objs.x,Objs.y,Objs.AnimatedImageData->width,Objs.AnimatedImageData->height);
          break;
      default:
          printf("I don't know wtf this object is.\n");
    }
  }
  
  return 0;
  
}
Re: Coding: Dynamically Defined Variables
May 06, 2010 03:03AM
Quote
tueidj
Well you need to at least give an accurate example if you want people to improve it. Let's try again.

If I provided my actual code then the source code would go on for pages...but the example was an accurate example.
However, you chose to *not* resolve the problem by the means outlines and instead chose to provide an alternate soution (which in some cases could be hepful but in this particular case it was not).

Quote
LordAshes
The reason why this is not possible is because the structure that image_data points to is not known at design time. In the simplified example above, it can point to either the startic or dynamic image structure. In my real code it can point to one of a hundred different structures. The decision as to which structure it points to is made at runtime.

Also, if you read the post carefully you would see that I specificaly mentioned that this is a simplified example where the real code can make use of any number of structures...hence the reason why your solution is not practical.

Thanks for your input anyway.
Re: Coding: Dynamically Defined Variables
May 06, 2010 09:47AM
How is it not practical? Do you expect C to somehow magically know what your structs will look like without defining them? Read the code again and go read up on how a union works in C. My second example is basically the same as Daid's but without the need for casting, which you couldn't seem to understand properly.
Re: Coding: Dynamically Defined Variables
May 06, 2010 01:50PM
That's it. If you want C to know about all ~500 types, you are going to have to program support for all of them. This isn't some scripting language where you just automagically throw things in variables.
Re: Coding: Dynamically Defined Variables
May 10, 2010 04:54PM
Quote
tueidj
Do you expect C to somehow magically know what your structs will look like without defining them?

Quote
WikiFSX
That's it. If you want C to know about all ~500 types, you are going to have to program support for all of them. This isn't some scripting language where you just automagically throw things in variables.

With all due respect, please READ the POST THREAD before responding...the two above answers are just a waste of posting space (no offense intended to the writers who are just trying to help) because the user obviously did not read the entire post thread. If they had they would not have written what they did since I am not trying to do either.

I stated numerous times that I WANT TO SPECIFY the structure to which the pointer points to. So this by definition means that I do NOT expect C to "magically know" and I am NOT "automatically throwing things in variables".

I have a pointer which can point to one of numerous structures. The decision as to which structure it will be, will be defined at runtime (not design time). The issue isn't with defining the structures (yes, you will need to define each one of the structures). The issue is with having only one pointer that points to one of the structures (instead of having a pointer for each possible structure even if it is not used). Clear?

So in addition to assigning to the pointer the address of the structure (at runtime) I would like to TELL C which structure the pointer is pointing at (during runtime) so that the -> references work.

Having said all that I have a guess at how to do it...I just have to actually try it to see if it will work...

I think the trick is to do the cast to one of the structures when you are USING the structure as opposed to when you are ASSIGNING the structure. So, for example:

printf("Object 0: (%d,%d)",((StaticImageType)Objs[0].image_data)->width,((StaticImageType)Objs[0].image_data)->height);

I'll let you guys know how it works.



Edited 2 time(s). Last edit at 05/10/2010 05:13PM by LordAshes.
Sorry, only registered users may post in this forum.

Click here to login