Reallocating pointers to a struct - c

I'm having an issue understanding this, my code below:
#include <stdio.h>
#include <stdlib.h>
typedef struct mee test;
typedef struct aa fill;
struct aa {
int c;
fill *point;
};
struct mee {
char name;
fill **a;
int b;
};
static fill **store;
static fill *talloc(int tsize);
static int mem;
static int ptr;
static fill *talloc(int tsize)
{ int temp;
temp = ptr;
ptr++;
mem = mem + tsize;
store = realloc(store, mem*sizeof(fill));
store[temp] = malloc(sizeof(fill));
return store[temp];
}
int main() {
test *t;
t = malloc(sizeof(test));
t->a = malloc(sizeof(fill *)*10);
printf("where\n");
for(int i= 0; i < 10; i++) {
t->a[i] = talloc(1);
}
printf("%d\n", store[9]->c); //Problem here
return 0;
}
excuse the terrible names, just some test code for a larger project. This code compiles and runs fine. if I set the code:
printf("%d\n", store[9]->c);
store[0-7] I get 0 as the output, though why does 8-9 give me some gibberish negative number? I'm assuming its a loss it the pointer somewhere.
How can I correct this?
For some background, this is to store pointers to struct in a array so I can free them a lot easier later.

Related

Dynamic Memory allocation of array inside structure in C

I'm doing dining-philosopher problem in C for assignment. And got stuck very begining of my code.
I decided each philosopher to be structure, and forks to be int array.
But I can't use global variable in this assignment.
So, I have to include shared variable in philosopher structure to pass them for arguments of thread routine.
Here is my problem - how to include int array in structure if I can't know proper size of them when initializing?
My plan is just include pointer variable in structure then allocate array's address using &.
But It doesn't work :
#include <stdlib.h>
/* inside structure*/
typedef struct s_share {
int **forks;
} t_share;
/* outside structure */
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
/* malloc structure arrary philo, size = 10 */
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
/* malloc int arrary forks, size = 100 */
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Output : segmentation fault
I tested share->forks size like this :
printf("size of forks : %ld\n", sizeof(philo->share->forks));
Output was 8.
It's enough size to store int * pointer.
Through this I know It's not the memory allocation problem.
Then what is problem? Can someone check this for me?
Edit :
When I try to malloc directly philo->share->forks, I got same error.
typedef struct s_share {
int *forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks = (int *)malloc(sizeof(int) * 100); //error
i++;
}
}
I thought it's because when philo initialized, sizeof operator calculated forks's memroy to be 8 - which required for pointer.
Is there something wrong?
Edit 2 :
To clear my question,
It's easy to solve this problem, if I write size of array in structure definition.
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
but according to my assignmet I have to get philosopher's number from cmd. So I can't do that.
Above is simple version of my origin code
Sorry, Edit 2 is wrong :
typedef struct s_share {
int forks[100];
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
while (i < 10)
{
philo[i].share->forks[i] = 1;
i++;
}
}
Output
zsh: segmentation fault ./a.out
I still got segfault when I write array size in struct definition.
I used calloc to initialize all member in my struct but same error occurs :
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
t_share *share;
int *forks;
int i;
i = 0;
philo = (t_philo *)calloc(10, sizeof(t_philo));
forks = (int *)calloc(100, sizeof(int));
while (i < 10)
{
philo[i].share->forks = &forks; //error
i++;
}
}
Edit 4:
I finally found error. It's because I didn't malloc 'share' struct in philo struct
typedef struct s_share {
int **forks;
} t_share;
typedef struct s_philo {
t_share *share;
} t_philo;
int main(void)
{
t_philo *philo;
int *forks;
int i;
i = 0;
philo = (t_philo *)malloc(sizeof(t_philo) * 10);
forks = (int *)malloc(sizeof(int) * 100);
while (i < 10)
{
philo[i].share = (t_share *)malloc(sizeof(t_share)); //here
philo[i].share.forks = &forks;
i++;
}
}
That one line -allocating struct share- solved problem.
Or, I can modify philo struct definition like this :
typedef struct s_philo {
t_share share; //not pointer, just struct
} t_philo;
In this way, I can automatically malloc struct share.
I got confused in this point. Thanks for helping!
this line
philo[i].share->forks
Is dereferencing the pointer 'share' which is not set. You called malloc and did not set any values, so the data inside your allocated buffer is 'garbage' data.
// add begin
t_share* new_share = (t_share*)malloc(sizeof(t_share));
philo[i].share = new_share;
// add end
// don't use &forks
philo[i].share->forks = forks; //error
i++;
// need forks++
forks++;

C iterate array by known sizeof

I'm trying to make a small library for particle management that allows to "expand" struct with user's data (texture, animation frames, etc). The library would know only the size of the expanded struct.
How do I iterate through the array of unknown struct types but known size of a struct?
typedef struct{
int type;
}Base;
typedef struct{
Base base;
int value;
}inherited;
int main(){
size_t size = sizeof(inherited);
int count = 10;
void *b = malloc(size * count);
for (int i = 0; i < count; i++){
// iterate based on known size & send to callback
callback( &( (size)b )[i] );
}
free(b);
return 0;
}
I assume the code that does the malloc and calls callback doesn't know anything about the type of the object, only its size.
#include <stdlib.h>
void *alloc_and_init(size_t nmemb, size_t size, void (*callback)(void *))
{
void *b = calloc(nmemb, size);
if (b)
{
char *p = b;
for (size_t i = 0; i < nmemb; i++)
{
callback(p);
p += size;
}
}
return b;
}
typedef struct{
int type;
}Base;
typedef struct{
Base base;
int value;
}inherited;
void init_inherited(void *p)
{
inherited *obj = p;
/* do initialization of obj->* here */
}
int main(void)
{
int objcount = 10;
inherited *objarr;
objarr = alloc_and_init(objcount, sizeof(*objarr),
init_inherited);
/* ... */
free(objarr);
}
for( inherited *p = b, *e = p + count; p < e; p++ ){
callback(p);
}
char *b = malloc(size * count);
for (int i = 0; i < count; i++){
// iterate based on known size & send to callback
callback( b + i * size );
}
Polymorphism in C is always rather clunky. Basically you have to construct a "vtable" manually. The naive, simplified version below lets each object have its own function pointer. You'll end up with something rather contrived like this:
#include <stdio.h>
#include <stdlib.h>
typedef struct base_t base_t;
typedef void callback_t (const base_t* arg);
struct base_t
{
int type;
callback_t* callback;
};
typedef struct
{
base_t base;
int value;
} inherited_t;
void callback_base (const base_t* arg)
{
puts(__func__);
}
void callback_inherited (const base_t* arg)
{
const inherited_t* iarg = (const inherited_t*)arg;
printf("%s value: %d\n", __func__, iarg->value);
}
int main (void)
{
// allocate memory
base_t* array [3] =
{
[0] = malloc(sizeof(inherited_t)),
[1] = malloc(sizeof(base_t)),
[2] = malloc(sizeof(inherited_t)),
};
// initialize objects
*(inherited_t*)array[0] = (inherited_t){ .base.callback=callback_inherited, .value = 123 };
*(array[1]) = (base_t){ .callback=callback_base };
*(inherited_t*)array[2] = (inherited_t){ .base.callback=callback_inherited, .value = 456 };
for (int i = 0; i < 3; i++)
{
array[i]->callback(array[i]); // now we get polymorphism here
}
}
A more professional version involves writing a translation unit (.h + .c) per "class" and then combine allocation with initialization in the "constructor". It would be implemented with opaque type, see How to do private encapsulation in C? Inside the constructor, set the vtable corresponding to the type of object allocated.
I'd also boldly claim that any OO solution using void* arguments has some design flaw. The interface should be using the base class pointer. Void pointers are dangerous.

how to do dynamic allocation in boundless array

Well I am wanting to change the way my structures are written, currently I use array and I need to limit its use, but I wanted a way to create a dynamic array that is the size of the reading done, without always having to edit the array value.
Current Code:
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag flag[50];
struct er_time time[50];
};
struct read_funcs
struct se_option *option;
void (*option_func) (void);
...
}
struct read_funcs func_;
struct read_funcs *func;
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
return func->option[i].flag[fg].value_flag = val;
}
void option_func(void) {
struct se_option fnc;
fnc.option = malloc(500 * sizeof(*(fnc.option)));
}
void read_fnc() {
func = &func_;
func->option = NULL;
func->option_func = option_func;
}
I look for a way to remove the array amount [50] instead each time the sr_flags function is executed the limit is raised
Example: sr_flags function executed 1x array would be [1] if executed 2x would be [2]
I also think about doing the same with the option_func function
I tried using the following more unsuccessfully
struct se_option {
struct sr_flag *flag;
struct er_time time[50];
};
int sr_flags(int i, int fg, int val) {
if(i < 0)
return 0;
func->option[i].flag = malloc(1 * sizeof(*(func->option[i].flag)));
return func->option[i].flag[fg].value_flag = val;
}
int main () {
for(int i < 0; i < 10; i++)
sr_flags(i, 1, 30);
return 0;
}
I'm not 100% certain on what it is you want but I think you just want to call realloc and increase the size by the amount you provide. And that's very easy to do, as for the values you want with the arrays I'm not sure so I just used a placeholder value.
#include <stdio.h>
#include <stdlib.h>
struct sr_flag {
int value_flag;
};
struct er_time {
int value_time;
};
struct se_option {
struct sr_flag* flag;
struct er_time* time;
};
void allocateflags(struct se_option* options, int size, int val){
options->flag = realloc(options->flag, size*sizeof(struct sr_flag));
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
}
void allocatetime(struct se_option* options,int size, int val){
options->time = realloc(options->time, size*sizeof(struct er_time));
struct er_time* time = options->time+size-1;
time->value_time = val;
}
void displayflagvalues(struct se_option* options,int size){
for(int index = 0; index < size ; ++index){
printf("flag: %i\n",options->flag[index].value_flag);
}
}
void displaytimevalues(struct se_option* options, int size){
for(int index = 0; index < size ; ++index){
printf("time: %i\n",options->time[index].value_time);
}
}
int main(){
struct se_option options = {0};
for(int index = 0; index < 10; ++index){
allocateflags(&options, index,index);
allocatetime(&options, index,index);
}
displayflagvalues(&options, 10);
displaytimevalues(&options,10);
return 0;
}
The code creates an se_option structure wheren sr_flag and er_time pointers are null. Then there's two functions one allocateflags and the other allocatetime, both of which call realloc with the size you provide. When you call realloc, all previous memory is copied over to the new array. Also free is called automatically by realloc.
This step
struct sr_flag* flag = options->flag+size-1;
flag->value_flag = val;
struct er_time* time = options->time+size-1;
time->value_time = val;
Is slightly redundant but it was just to show the newest array can hold the value. If you understand pointer arithmetic, all its doing is incrementing the pointer to the last position then subtracting 1 struct size and setting that value. Basically setting the value of the final array in the pointer.

Printing Wrong Data

So I'm trying to simulate a cache. Right now, I created structs for the blocks and the sets and created their constructors. When the constructor for cache set are activated it initilize all of the tags and valid bits to 0. However, I keep getting garbage data printed out for the tags.I'm probably set up my pointer incorrectly, but I having problems figuring out what.
#include <inttypes.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
uint64_t tag;
unsigned int valid_bit;
}block;
typedef struct
{
unsigned int set_bit;
unsigned int number_of_blocks;
block * blocks;
}cache_set;
block *make_A_BLOCK(uint64_t tg, unsigned int v_b)
{
block *b = malloc(sizeof(block));
b->tag = tg;
b->valid_bit = v_b;
return b;
}
void change_tag(block *b,uint64_t t_g){b->tag = t_g;}
void change_bit(block *b,unsigned int v_b){b->valid_bit = v_b;}
uint64_t return_tag(block *b){ return b->tag;}
unsigned int return_bit(block *b){ return b->valid_bit;}
cache_set *make_A_CACHE_SET(unsigned int s_b, unsigned int n_b)
{
int i;
//uint64_t blank = 0;
cache_set *c_s = malloc(sizeof(cache_set));
c_s->set_bit = s_b;
c_s->number_of_blocks = n_b;
block *blocks = malloc(n_b * sizeof(block));
for (i=0; i < n_b; i++)
{
blocks[i].tag = 0;
blocks[i].valid_bit = 0;
}
free(blocks);
return c_s;
}
void print_cache_set(cache_set *c_s)
{
int i;
printf("Number of Cache Sets: %d \r\n",c_s->number_of_blocks);
for (i= 0; i < c_s->number_of_blocks ; i++)
{
printf("Block %d ",i);
printf(" Block Tag " "%" PRIu64, return_tag(&(c_s->blocks[i])));
//printf(" Block Bit %d \r\n", blocks[i].valid_bit);
}
}
int main(void)
{
cache_set *test = make_A_CACHE_SET(0,10);
print_cache_set(test);
printf("done");
return 0;
}
Example
When making a cash_set, you allocate blocks and assign the pointer to them to a local variable, and then you initialize the blocks one after the other.
But then, instead of letting the c_s->blocks point to this initialized list of blocks, you deallocate them with free(blocks).
So I'd suggest to replace free(blocks) by c_s->blocks = blocks

C struct example, errors during compilation

I am trying to get familiar with struct and pointers in C and I am running into a bunch of syntax errors like "missing ';' before type", "missing ')' before type" and "undeclared identifier: 'i'". Everything seems fine, I know i is declared and I don't seem to be missing any ; or ).
#include <stdlib.h>
#include <stdio.h>
#pragma warning(disable: 4996)
struct Room;
struct House;
struct Room
{
float width;
float length;
float height;
char *name;
};
struct House
{
char *address;
struct Room *rooms[10];
};
int main(int argc, char* argv[])
{
struct House h;
h.address = "10 Palace Road";
for(int i = 0; i < 10; i++) // 6 errors occur here
{
h.rooms[i] = NULL;
}
struct Room hall;
hall.width = 10;
hall.length = 12;
hall.height = 9;
hall.name = "Hall";
h.rooms[0] = &hall;
printHouse(h);
system("PAUSE");
return 0;
}
void printHouse(struct House house)
{
printf(house.address);
printf("\n\n\n");
for (int i=0; i<10; i++)
{
if (house.rooms[i] != NULL)
{
struct Room r = *house.rooms[i];
printf("Room # %d: %s", i+1, r.name);
}
}
}
printf(house.address);
should be
printf("%s",house.address);
Also you must declare your function printhouse, since you have defined it after main.
#include <stdlib.h>
#include <stdio.h>
#pragma warning(disable: 4996)
struct Room; //you don't need this
**EDIT**
struct House
{
char *address;
struct Room *rooms[10];
};
void printHouse(struct House house);
Declare House first then the function.
int i;
for (i = 0; i < 10; i++){
//...
}
In earlier versions of C, you cannot declare I inside a loop.
Some versions of C compilers do not allow 'i' to be declared in the loop. Try declaring 'i' separately at the beginning of 'main()'. That should work.

Resources