Implement a set using structure but it is giving errors [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
It is giving error in pushintoset function that array undeclared first use in this function
invalid type argument of '->' (have 'int')
#include <stdio.h>
#include <stdlib.h>
struct set
{
int data1;
int data2;
int size;
int *array;
int index;
};
struct set *createset(int capacity)
{
struct set * s = (struct set*)malloc(sizeof(struct set));
s->size = capacity;
s->array = (int *)malloc(sizeof(int) * s->size);
return s;
}
void pushintoset(struct set *st) //giving error in this function that array undeclared
{
int item1;
int item2;
int i;
for(i=0;i<5;i++)
{
printf("enter set %d \n",i);
scanf("%d %d",&item1,&item2);
st->index = i;
st->array[st->index]->data1 = item1;
st-array[st->index]->data2 = item2;
st->array[st->index]->index = i;
}
}
void printset(struct set * s)
{
int i;
for(i=1;i<=5;i++)
{
printf("%d \t %d \n",s->array[i]->data1,s->array[i]->data2);
}
}
int main()
{
struct set * se = createset(5);
if(se==NULL)``
printf("memory not allocate");
pushintoset(se);
printset(se);
return 0;
}

st-array[st->index]->data2 = item2; // loss of '>' after 'st-'
and you should not access struct member array as a struct point here.

Can you be more specific ?
What are you trying to do in these lines
st->array[st->index]->data1 = item1;
st-array[st->index]->data2 = item2;
st->array[st->index]->index = i;
st is a pointer to struct set and you can access its variable
st-> structure member
you can access data1 and data2 this way
st->data1 and st->data2

data1 and data2 is part of set structure. They are not member of st->array. st->array is type of int *. You should try st->data1 , st->data2.

You try to access
st->array[st->index]->data1
st->array[st->index] is of type int, you can't access ->data2?
In your main you instantiate a strut set with an internal array size of 5, then you pass it to pushIntToSet(), the code should be instead:
void pushintoset(struct set *st)
{
int item1;
int item2;
int i;
if (set == NULL) //checking for null ptr
return ;
printf("Enter two numbers for set [%d] \n", i);
scanf("%d %d", &item1, &item2);
st->data1 = item1;
st->data2 = item2;
}
It's probably not what you wanted to do, but the array is just an int array and hae nothing to do with data1/data2.

You are creating a single pointer array and instead of storing the values directly you are storing int type.
see the below code it is working fine.
#include<stdio.h>
#include<stdlib.h>
struct set
{
int data1;
int data2;
int size;
int *array;
int index;
};
struct set *createset(int capacity)
{
struct set * s = (struct set*)malloc(sizeof(struct set));
s->size = capacity;
s->array = (int *)malloc(sizeof(int) * s->size);
return s;
}
void pushintoset(struct set *st) //giving error in this function that array undeclared
{
int item1;
int item2;
int i;
for(i=0;i<5;i++)
{
printf("enter set %d \n",i);
scanf("%d %d",&item1,&item2);
st->index = i;
st->array[st->index] = item1;
st->array[st->index] = item2;
st->array[st->index] = i;
}
}
void printset(struct set * s)
{
int i;
for(i=1;i<=5;i++)
{
printf("%d \t %d \n",s->array[i],s->array[i]);
}
}
int main()
{
struct set * se = createset(5);
if(se==NULL)
printf("memory not allocate");
pushintoset(se);
printset(se);
return 0;
}
see it on live here
https://ideone.com/TXBpsP

When you look at the three lines:
st->array[st->index]->data1 = item1;
st-array[st->index]->data2 = item2;
st->array[st->index]->index = i;
You should spot the misalignment.
st - array
references the variable array, which is not defined. That's why you're getting the mention of array being undefined. You're missing the > necessary to make it compile.
When you fix that, you have a problem that st->array is an integer pointer; you're trying to treat it as an array of pointers to your structure type.

void pushintoset(struct set *st) //giving error in this function that array undeclared
{
int item1;
int item2;
int i;
for(i=0;i<5;i++)
{
printf("enter set %d \n",i);
scanf("%d %d",&item1,&item2);
st->index = i;
// st->array[st->index] is ok
// but st->array[st->index]->data1 is wrong
// array is a pointer of int as your define,
// it isn't a strcut, have no member data1 and data2
// and the other probelm, wild pointer!
// you use it as a array without initialize it (Memory allocation)
st->array[st->index]->data1 = item1; // ??
st-array[st->index]->data2 = item2;
st->array[st->index]->index = i;
}
}

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.

Why am I getting "ERROR : request for member stringLength and name in something not a structure or union"?

I'm trying to implement a stack and its basic properties (push, pop, etc.) but I'm getting the error I mentioned in the title:
ERROR : request for member stringLength and name in something not a structure or union
#include <stdio.h>
#include <stdlib.h>
typedef struct stackElement
{
int stringLength;
char *name;
} StackElement;
int Push(StackElement **stack);
int main()
{
StackElement *stack = NULL;
int index = 0;
index = Push(&stack);
printf("The top word of the stack is %s\n", stack[index].name);
system("PAUSE");
return 0;
}
int Push(StackElement **stack)
{
char *c;
int size = 0;
int i = 0;
*stack = malloc(sizeof(StackElement));
printf("Please enter a word in the stack\n");
scanf("%s",&c);
size = sizeof(c)/sizeof(char);
*stack[i].stringLength = size;// <---- ERROR
*stack[i].name = c ;// <----- ERROR
return i;
}
It's an operator precedence issue.
. has higher precedence than *, so:
*stack[i].stringLength
Is the same as
*(stack[i].stringLength)
While you actually want
(*stack[i]).stringLength
Just add the brackets as I did in the last example and it should work.

pointers/structures

I would like to ask question regarding pointers. I dont know what to do here, I have a method in the main that is calling a method outside the main, and I need to use pointers.Basically this is the rough draft of it: Thanks!
char *book[] = { "x", "y", "z",};
int number[] = { 1, 2, 3};
struct data{ char *bookname; int booknumber;};
struct data *list[3];
my_method(char *x, int y, int *z)
{
//creating a new struct
list[(*z)++] = (struct data*) malloc( sizeof(struct data) );
//assigning arguments
list[(*z)++]->bookname = x;
list[(*z)++]->booknumber = y;
(*z)++;
}
int main()
{
int nextValue = 0;
my_method(book[nextValue], book[nextValue], &nextValue);
int i;
for(i = 0; i < 3; i++)
{
function(book[i], number[i]);
printf("name: %c number: %d", list[i]->bookname, list[i]->booknumber);
}
}
It looks like you are passing the wrong arguments to your method. Try changing the following line:
my_method(book[nextValue], number[nextValue], &nextValue);
In addition, in your method you seem to be incrementing z four times, which I doubt is the behavior you want. You should only increment it once at the end, like the following:
//creating a new struct
list[*z] = (struct data*) malloc( sizeof(struct data) );
//assigning arguments
list[*z]->bookname = x;
list[*z]->booknumber = y;
(*z)++;
Try the following code. Simply removed unnecessary static void.
//declaration of method outside the main
void my_method(............,int *nextValue)
{
//................................//
//..............................//
//then increment the pointer
(*nextValue)++;
}//my_method
int main()
{
int nextValue = 0;
//Removed static void
my_method(............, &nextValue);
//........................................//
}//main

Resources