In a project I'm writing code for, I have a void pointer, "implementation", which is a member of a "Hash_map" struct, and points to an "Array_hash_map" struct. The concepts behind this project are not very realistic, but bear with me. The specifications of the project ask that I cast the void pointer "implementation" to an "Array_hash_map" before I can use it in any functions.
My question, specifically is, what do I do in the functions to cast the void pointers to the desired struct? Is there one statement at the top of each function that casts them or do I make the cast every time I use "implementation"?
Here are the typedefs the structs of a Hash_map and Array_hash_map as well as a couple functions making use of them.
typedef struct {
Key_compare_fn key_compare_fn;
Key_delete_fn key_delete_fn;
Data_compare_fn data_compare_fn;
Data_delete_fn data_delete_fn;
void *implementation;
} Hash_map;
typedef struct Array_hash_map{
struct Unit *array;
int size;
int capacity;
} Array_hash_map;
typedef struct Unit{
Key key;
Data data;
} Unit;
functions:
/* Sets the value parameter to the value associated with the
key parameter in the Hash_map. */
int get(Hash_map *map, Key key, Data *value){
int i;
if (map == NULL || value == NULL)
return 0;
for (i = 0; i < map->implementation->size; i++){
if (map->key_compare_fn(map->implementation->array[i].key, key) == 0){
*value = map->implementation->array[i].data;
return 1;
}
}
return 0;
}
/* Returns the number of values that can be stored in the Hash_map, since it is
represented by an array. */
int current_capacity(Hash_map map){
return map.implementation->capacity;
}
You can cast it each time you use it, or you can cast it once and save the value to a temporary variable. The latter is usually the cleanest method.
For example, you could use something like:
void my_function (Hash_Map* hmap) {
Array_hash_map* pMap;
pMap = hmap->implementation;
// Now, you are free to use the pointer like it was an Array_hash_map
pMap->size = 3; // etc, etc
}
Related
I am trying to understand an assignment I have before I have to take a final. I am trying to understand what exactly I am declaring.
So in a given file the typedef struct's are declared as so:
(Struct Declaration)
/** The following two structs must be defined in your <gamename>.c file **/
typedef struct game_position_t *game_position;
/* move struct must code enough information to reverse the move, given the resulting position */
typedef struct move_t *move;
I have then built the structs out as so (yes this has to be separated just because it is interfaced programming):
(Struct Definition)
/** The following two structs must be defined in your <gamename>.c file **/
struct game_position_t {
int mathy;
int numrows;
int *sizes;
};
/* move struct must code enough information to reverse the move, given the resulting position */
struct move_t {
int rownum;
int move_size;
};
Then an example of a functions and declaration of game_position for example is:
(Example Function)
/* return the starting position, NULL if error */
game_position starting_position(int me_first, int argc, char **argv) {
if (argc < 3) {
printf("\n\nToo few arguments, see help below\n\n");
game_help(argv[0]);
return NULL;
}
int mathy;
if (strcmp(argv[2],"search")==0)
mathy = 0;
else if (strcmp(argv[2],"mathy")==0)
mathy = 1;
else {
printf("\n\nSecond argument must be \"search\" or \"mathy\", see help below\n\n");
game_help(argv[0]);
return NULL;
}
int play_default = (argc==3);
if (play_default) printf("\n\nOK, we will play the default game of 7 5 3 1\n\n");
int defaultgame[4] = {7,5,3,1};
game_position result = malloc(sizeof(struct game_position_t)*1);
result->mathy = mathy;
if (result) {
result->numrows = (play_default ? 4 : argc-3);
result->sizes = malloc(sizeof(int)*(result->numrows));
int row;
for (row=0; row<(result->numrows); row++)
(result->sizes)[row] = (play_default ? defaultgame[row] : strlen(argv[row+2]));
}
return result;
}
So my main misunderstanding is when using a struct declaration in this manner, specifically putting the * before the name like this, typedef struct move_t *move;. Is that previous line saying move it a struct pointer or dereferencing move? Continuing from that. When defining them I just use the struct name such as struct move_t. I don't fully understand how they are linking together and in what matter. Then inside the function I just declare game_position, but still need to use a derefencer, 'p->`, to access it fields. So if someone could explain to me when these struct variables are points to structs and when they are the actual struct.
An example of my misunderstanding is that in the Example Function after result was declared. I first thought to use the . operator to access and set it's fields. I then changed it due to compiler errors, but now I want to understand my misunderstanding. And why did I I have to malloc game_position_t and not game_position?
typedef defines a type, so typedef struct move_t *move defines a new type named move, which is a pointer type, pointing to struct move_t. So after this if you define a variable with move ptr, ptr will have a pointer type so that you should use the syntax of accessing members through a pointer. When allocating memory for it, of course you have to specify the exact size of the structure other than the size of a pointer, that's sizeof(struct move_t)
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes. This structure's definition needs to be global since I am going to use that type thereafter in my program. It is necessary to have a dynamic size for this structure because I will have a HUGE database populated by that type of variables in the end.
The code I have right now is:
struct user_defined_integer;
.
.
.
void def_type(int num_bits)
{
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
return;
}
(which is not working)
The closest thing to my question, I have found, is in here:
I need to make a global array in C with a size inputted by the user
(Which is not helpful)
Is there a way to do this, so that my structure is recognized in the whole file?
When doing:
extern struct user_defined_integer
{
int val[num_bits/sizeof(int)];
};
You should get the warning:
warning: useless storage class specifier in empty declaration
because you have an empty declaration. extern does not apply to user_defined_integer, but rather the variable that comes after it. Secondly, this won't work anyway because a struct that contains a variable length array can't have any linkage.
error: object with variably modified type must have no linkage
Even so, variable length arrays allocate storage at the point of declaration. You should instead opt for dynamic memory.
#include <stdlib.h>
typedef struct
{
int num_bits;
int* val;
} user_defined_integer;
void set_val(user_defined_integer* udi, int num_bits)
{
udi->num_bits = num_bits;
udi->val = malloc(num_bits/sizeof(int));
}
What you need is a VLA member, as asked about here. Basically, you declare a struct with a size field and one element's worth of storage as last member, and over-allocate it.
Imported from that question :
typedef struct Bitmapset {
int nwords;
uint32 words[1];
} Bitmapset;
Bitmapset *allocate(int n) {
Bitmapset *p = malloc(offsetof(Bitmapset, words) + n * sizeof *p->words);
p->nwords = n;
return p;
}
I want to define a new data type consisting of an array with a size inputted by the user. For example if the user inputs 128, then my program should make a new type which is basically an array of 16 bytes.
This is not possible in C, because C types are a compile-time thing and don't exist at all at run-time.
However, with a C99 conforming compiler, you might use flexible array member. You'll need a struct containing some members and ending with an array without any given dimension, e.g.
struct my_flex_st {
unsigned size;
int arr[]; // of size elements
};
Here is a way to allocate it:
struct my_flex_st *make_flex(unsigned siz) {
struct my_flex_st* ptr
= malloc(sizeof(struct my_flex_st) + siz * sizeof(int));
if (!ptr) { perror("malloc my_flex_st"); exit(EXIT_FAILURE); };
ptr->size = siz;
memset (ptr->arr, 0, siz*sizeof(int));
return ptr;
}
Don't forget to free it once you don't use it anymore.
Of course, you'll need to use pointers in your code. If you really want to have a global variable, declare it as e.g.
extern struct my_flex_st* my_glob_ptr;
Try this method-
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
struct user_defined_integer
{
int *val;
}user_int;
void memory_allocate(int num_bit)
{
int result;
result = (num_bit+CHAR_BIT-1)/CHAR_BIT; // since 8 bit =1 byte
user_int.val=malloc(result*sizeof(int));
if(user_int.val == NULL){
printf("Failed to allocate memory\n");
return ;
}
else
printf("Allocated %d bytes for val\n",result);
}
int main()
{
int num_bit;
printf("Enter the number of bits\n");
scanf("%d",&num_bit);
memory_allocate(num_bit);
// do your stuff here
free(user_int.val); // free the memory at the end;
return 0;
}
My college professor taught us that a generic stack looks something like this (I basically copy-pasted this from the course support files):
typedef struct
{ size_t maxe, dime;
char *b, *sv, *vf;
} TStiva, *ASt;
#define DIME(a) (((ASt)(a))->dime)
#define BS(a) (((ASt)(a))->b)
#define SV(a) (((ASt)(a))->sv)
#define VF(a) (((ASt)(a))->vf)
#define DIMDIF(s,d) (DIME(s) != DIME(d))
#define VIDA(a) (VF(a) == BS(a))
#define PLINA(a) (VF(a) == SV(a))
// Function Declarations
void* InitS(size_t d,...);
int Push(void* a, void* ae);
int Pop (void* a, void* ae);
int Top (void* a, void* ae);
void *InitS(size_t d,...)
{ ASt a = (ASt)malloc(sizeof (TStiva));
va_list ap;
if (!a) return NULL;
va_start(ap,d);
a->maxe = va_arg(ap,size_t);
va_end(ap);
a->dime = d;
a->b = (char*)calloc(a->maxe, d);
if (!a->b) { free(a); return NULL; }
a->vf = a->b;
a->sv = a->b + d * a->maxe;
return (void *)a;
}
int Push(void *a, void *ae)
{ if( PLINA(a)) return 0;
memcpy (VF(a), ae, DIME(a));
VF(a) += DIME(a);
return 1;
}
int Pop(void *a, void *ae)
{ if(VIDA(a)) return 0;
VF(a) -= DIME(a);
memcpy (ae, VF(a), DIME(a));
return 1;
}
int Top(void *a, void *ae)
{ if(VIDA(a)) return 0;
memcpy (ae, VF(a)-DIME(a), DIME(a));
return 1;
}
Anyway, what this wants to be is a generic stack implementation with vectors, from which I don't understand why in the Top, Push and Pop functions need to refer to the stack data structure as a void *.
By generic, doesn't it want to mean that the value the data structure wants to hold is generic? This meaning that if you refer to your generic data structure as the typedef instead of void * it doesn't certainly mean that it's not generic.
I am asking this because I am about to create a Generic Stack implemented with Linked Lists and I am a bit confused.
This is my generic linked list data structure:
typedef struct Element {
struct Element *next;
void *value;
} TElement, *TList, **AList;
And for the Stack:
typedef struct Stack {
size_t size;
TList top;
} TStack, *AStack;
/* Function Definitions */
TStack InitStack(size_t);
void DeleteStack(AStack);
int Push(TStack, void*);
int Pop(TStack, void*);
int Top(TStack, void*);
Does anything seem not generic in my implementation?
Generic means that it can hold ANY data type (char*, int*, etc..), or contain any data type. Void pointers void * in C allow you to cast items as such and get those items out(having to re-cast them on retrieval.
So, it allows the program to be ignorant of the data types that you have in your custom data structure.
Referring to the structure itself(as long as you are not specifying the data that is held in said structure), does not break generalities. So, you can specifically mention your TStack in your functions as long as the data that is manipulated inside of that stack is general(id est void *).
void* is for generic purposes. Imagine it as a pointer to the memory, where of course the memory can hold anything. By void* you mean that you do not know what you point to, but you know that you point to something.
Yes a void*can correctly implement a generic stack, but that creates a problem that you have no idea about the type of data you are storing in the Stack. The concept of void* is that it is pointing to some valid block of memory, but there is absolutely no clue as to the type of the memory. So, the code that is using this generic stack has to do type conversion explicitly. void* are used only to store data, manipulation with them are disallowed.
I'm writing a Gameboy ROM using the GBDK, which has an unstable version of malloc that I'm unable to get working. I'm also unable to return a struct within a struct. That leaves me trying to return a pointer, which is why I'm wondering if there is a way to avoid using malloc when returning a struct pointer?
What I'm basically trying to do is that I want to be able to write something like this:
create_struct(struct_name, char member_x, char member_y);
This is the code I have written using malloc:
struct point {
char member_x;
char member_y;
};
struct point *makepoint(char member_x, char member_y) {
struct point *temp = malloc(sizeof(struct point));
temp->member_x = member_x;
temp->member_y = member_y;
return temp;
};
There are various valid ways to return a pointer (to a struct, or any type of object), but the only way to return a pointer to a new object that didn't exist before the function was called is to use malloc, realloc, calloc, aligned_alloc (C11), or some implementation-defined allocation function (e.g. mmap on POSIX systems, etc.).
Other ways you could return a valid pointer include:
A pointer to an object with static storage duration. Only once instance of such an object exists, so this is usually a bad way.
A pointer that was passed to the function as an argument for use as a place to store the result. This can often be a good approach, since you pass off responsibility for obtaining the storage to the caller.
A pointer to an object obtained from some sort of global pool. This could be a very good approach in embedded systems and game design for low-end gaming devices.
Is it possible to return a pointer to a struct without using malloc?
I. Technically, yes. You can make your struct static so that it survives function calls:
struct foo *bar()
{
static struct foo f = { 1, 2, 3 };
return &f;
}
But I doubt you actually want to do this (since this has funny side effects, read up on the meaning of the static keyword). You have several different possibilities:
II. The approach what the C standard library takes is always making the caller implicitly responsible for providing the struct and managing memory. So instead of returning a pointer, the function accepts a pointer to struct and fills it:
void dostuff(struct foo *f)
{
foo->quirk = 42;
}
III. Or return the struct itself, it doesn't hurt, does it (it can even be move-optimized):
struct foo bar()
{
struct foo f = { 1, 2, 3 };
return f;
}
So, choose your poison.
just do something like:
void makepoint(struct point *dest, char member_x, char member_y) {
dest->member_x = member_x; // you had these wrong in your code, by the way
dest->member_y = member_y;
}
The structure will need to be "allocated" elsewhere (probably on the stack is your best bet).
You could pass the struct as a parameter and have the function initialize it :
struct point *makepoint(struct point *pt, char x, char y) {
pt->x = x;
pt->y = y;
return pt;
}
and then call it like this :
struct point pt;
makepoint(&pt, 'a', 'b');
but then you might as well just have done :
struct point pt = { 'a', 'b' };
Note that in this case (struct point only occupies 2 bytes) you can return struct point instead of struct point *, (this should not be done with large structs)
#include <stdio.h>
struct point {
char member_x;
char member_y;
};
struct point makepoint(char member_x, char member_y)
{
struct point temp;
temp.member_x = member_x;
temp.member_y = member_y;
return temp;
}
int main(void)
{
struct point t = makepoint('a', 'b');
printf("%c %c\n", t.member_x, t.member_y);
return 0;
}
If it is not possible to get malloc() fixed, then you may just want to manage your own pre-allocated points, and limit the number of points that can be "created". You would need to alter your points a little to allow for easier management:
union free_point {
union free_point *next;
struct point data;
};
union free_point free_point_pool[MAX_POINTS];
union free_point *free_point_list;
struct point *makepoint(char member_x, char member_y) {
static int i;
union free_point *temp;
temp = 0;
if (i == MAX_POINTS) {
if (free_point_list) {
temp = free_point_list;
free_point_list = temp->next;
}
} else {
temp = free_point_pool + i++;
}
if (temp) {
temp->data.x = x;
temp->data.y = y;
}
return &temp->data;
};
Then, instead of calling free() on the result returned by makepoint(), you should create a new function to place it on the free_point_list.
void unmakepoint (struct point *p) {
union free_point *fp = (union free_point *)p;
if (fp) {
fp->next = free_point_list;
free_point_list = fp;
}
}
The simplest thing is just to return a structure that has been created using named initializers, and do so in an inline function, so that there is zero overhead:
static inline struct point makepoint(char x, char y) {
return (struct point) { .x = x, .y = y };
}
Then you can call it like this:
struct point foo = makepoint(10, 20);
Couldn't be simpler!
I'm trying to create a stack in C for fun, and came up with the idea of using struct to represent the stack. Then I add function pointers to the struct for push() and pop() operations.
So far all is good it seems, but, for the implementation of the push() and pop() functions I need to refer to *this somehow. How can that (can it?) be done?
This is my struct
struct Stack {
int *data;
int current_size;
int max_size;
int (*push)(int);
int (*pop)();
};
And as an example here's push
int push(int val) {
if(current_size == max_size -1)
return 0;
data[current_size] = val;
current_size++;
return 1;
}
As you can imagine, the compiler has no idea what current_size is, as it would expect something like stack->current_size.
Is this possible to overcome somehow?
There's no implicit this in C. Make it explicit:
int push(Stack* self, int val) {
if(self->current_size == self->max_size - 1)
return 0;
self->data[self->current_size] = val;
(self->current_size)++;
return 1;
}
You will of course have to pass the pointer to the struct into every call to push and similar methods.
This is essentially what the C++ compiler is doing for you when you define Stack as a class and push et al as methods.
The typical approach in C is to have functions expect this as the first parameter.
int push(Stack *self, int val)
{
if (self->current_size == self->max_size -1) return 0;
self->data[self->current_size++] = val;
return 1;
}
This has the added benefit that, unless you need polymorphism, you don't need to put the functions in the stack, because you could just call push(stack, 10) instead of stack->push(stack,10).
C doesn't work like that. It's not an object oriented language. Functions that manipulate data structures need to take a pointer to the structure as an argument.
In header file you can declare static this variable
static struct Stack *this;
And then in push method you can use this variable
static int push(int val) {
if(this->current_size == this->max_size - 1)
return 0;
this->data[this->current_size] = val;
(this->current_size)++;
return 1;
}
The caveat is you have to manually set this variable through some method before you want to invoke other methods, eg:
struct Stack {
struct Stack (*_this)(struct Stack *); // <-- we create this method
int *data;
int current_size;
int max_size;
int (*push)(int);
int (*pop)();
};
And then we can implement _this method as
static struct Stack *_this(struct Stack *that)
{
retrun this = that;
}
The example:
struct Stack stack1, stack2;
... some initialization ...
stack1->_this(&stack1)->push(0);
stack1->push(1);
stack1->push(2);
stack2->_this(&stack2);
stack2->push(10);
stack2->push(20);
Your function pointers aren't methods so they don't have any information about the calling object. The only way to do what you want is to either pass in a pointer to the object, or make that pointer global (the latter is not recommended).
Obviously you can have a Stack * member in the struct and then just initialize it with the address of the struct before you use the function pointers. Then make the Stack * a parameter on the function pointers.
Since your are going to have only one Stack structure (that you named stack, apparently), you could define it as a global variable. This would allow pop/push to refer to the stack variable directly.
You would do something like:
stack.current_size += 4;
or use the -> operator if you decide to declare stack as a memory pointer to Stack.