how to initialize struct array members inside function by reference - c

im trying to make an array of struct and initialize struct array member, but I don't know how to access struct member, i used (st->ch)[t] = 'c'; and others similar syntax but i did not succeed.
best regards.
struct ST
{
char ch;
};
bool init(ST* st, int num)
{
st = (ST*)malloc(num * sizeof(ST));
if (st == NULL) return false;
for (int t = 0; t < num; t++) (st->ch)[t] = 'c';
return true;
}
int main()
{
ST* s = NULL;
init(s, 2);
putchar(s[1].ch);
}

You declared in main a pointer
ST* s = NULL;
that in C shall be declared like
struct ST* s = NULL;
because you declared the type specifier struct ST (that in C is not the same as just ST)
struct ST
{
char ch;
};
that you are going to change within a function. To do that you have to pass the pointer to the function by reference. That is the function declaration will look at least like
bool init( struct ST **st, int num );
and the function is called like
init( &s, 2);
if ( s ) putchar( s[1].ch );
The function itself can be defined like
bool init( struct ST **st, int num )
{
*st = malloc( num * sizeof( struct ST ) );
if ( *st )
{
for ( int i = 0; i < num; i++) ( *st )[i].ch = 'c';
}
return *st != NULL;
}
If you are using a C++ compiler then substitute this statement
*st = malloc( num * sizeof( struct ST ) );
for
*st = ( struct ST * )malloc( num * sizeof( struct ST ) );
When the array of structures will not be needed you should free the memory occupied by the array like
free( s );

You can access struct member using following:
st[t].ch

As mentioned by #kaylum st being a local variable in the init() and doesn't update the variable s in the main function hence an alternative could be you either pass the add the address of the variable s to init() or could just return the allocated memory as shown in the code snippet below. Instead of using bool as return type to check you can use the ST* as return type and if it returns NULL or mem address to get mem alloc status.
Also you would have to typedef the struct typedef struct ST ST; to be able to directly use the type as ST else you would have to stick to using struct ST
typedef struct ST
{
char ch;
}ST;
ST* init(int num)
{
ST *st;
// Create num elems of ST type
st = (ST*)malloc(num * sizeof(ST));
// return NULL is st unintialised
if (st == NULL) {
return st;
}
// Assign ch member variable of the 't'th st element wit 'c'
for (int t = 0; t < num; t++) {
st[t].ch = 'c';
}
return st;
}
int main()
{
ST* s;
// creates an array of size two of type st
s = init(2);
putchar(s[1].ch);
return 0;
}

Related

How to access the value of a struct member which stores return value of a function pointer?

I have the following structure definitions:
typedef struct S_t S_t;
struct S_t {
float *s_ptr;
uint32_t ns;
};
typedef struct p_t p_t;
struct p_t {
int32_t pID;
float pVal;
};
typedef struct pr_t pr_t;
struct pr_t {
S_t *S;
int (*TrimS)(S_t *TS, int sSize);
p_t *TP;
};
I also have the following function defined:
int success = 0;
int failure = -1;
int ChopS(S_t *TS, int size)
{
int i, c;
for(i = 0; i < TS->ns; i++)
{
if (i >= size)
TS->s_ptr[i] = 0.0;
}
c = 0;
for(i = 0; i < TS->ns; i++)
{
if(TS->s_ptr[i] == 0.0)
c++;
}
if (c == size)
return success;
else
return failure;
}
I do the following (full code here) to assign values to each member of type pr_t , one of whose member is TrimS which is a status flag function pointer:
p_t *p2 = NULL;
S_t *tS2 = NULL;
tS2 = malloc(sizeof(S_t));
pr_t *SP2 = NULL;
SP2 = malloc(sizeof(pr_t));
p2 = (p_t *) malloc(sizeof(p_t));
SP2->S = tS2;
SP2->TP = p2;
SP2->TrimS = ChopS;
SP2->TrimS(tS2, 8);
If I try to access the value of the flag using SP2->TrimS, I get a junk value (or an address value I think) but not 0 or -1 as I expect. What is exactly happening over here? How can I access the value set by ChopS in SP2->TrimS?
You need to call the function to get the return value. It is not stored anywhere and the function pointer does not store the last return value. Use it as any "normal" function
if(SP2->TrimS(tS2, 8) == failure)
{
/* do something */
}
else
{
/* do something else */
}
or if you want to access it later (after the call) you need to store it in the variable or have an additional struct member to store it:
struct pr_t {
S_t *S;
int (*TrimS)(S_t *, int);
int last_TrimS_Return_Value;
p_t *TP;
};
/* .... */
SP2 -> last_TrimS_Return_Value = SP2->TrimS(tS2, 8);

Compilation error on creating nodes of a BST from a struct

In my code, there is a binary tree struct defined as :
typedef struct bintreestruct *bintree;
struct bintreestruct
{
double num;
char *s;
bintree l, r;
};
I wanted to insert a node into this binary search tree. Here is the function:
void insbintree(double i, char *s, bintree *t)
{
if (t == NULL)
{
bintree temp = (struct bintreestruct *)malloc(sizeof(struct bintreestruct));
temp->s = s;
temp->num = i;
temp->l = temp->r = NULL;
return temp;
}
if (strcmp(s, t->s) < 0)
t->l = insert(t->l, s);
else if (strcmp(s, t->s) >= 0)
t->r = insert(t->r, s);
return t;
}
I am getting the error error: ‘*t’ is a pointer; did you mean to use ‘->’? 62 | if (strcmp(s, t->s) < 0)
Either I am creating the new node incorrectly or accessing the elements inside in
the wrong way using pointers. Not sure how to correct this error
It seems you are trying to write a recursive function because it calls itself.
As the function has return statements with expressions then its return type shall not be void.
Also this parameter declaration bintree *t is equivalent to struct bintreestruct ** due to this typedef
typedef struct bintreestruct *bintree;
But within the function you are trying to use it as having the type struct bintreestruct *.
And in these calls of the function itself
t->l = insert(t->l, s);
t->r = insert(t->r, s);
there are used incomplete and not correctly ordered lists of arguments.
Taking all this into account the function can be declared and defined at least the following way
bintree insbintree(double i, char *s, bintree t)
{
if (t == NULL)
{
t = malloc( sizeof( struct bintreestruct ) );
t->s = s;
t->num = i;
t->l = t->r = NULL;
}
else if ( strcmp(s, t->s) < 0 )
{
t->l = insert(i, s, t->l);
}
else
{
t->r = insert(i, s, t->r );
}
return t;
}
Pay attention to that using the typedef declaration for the pointer type is a bad idea. It only confuses readers of the code.

dynamically allocate arrays of pointers to structures in C

I have this structure here:
typedef struct _open {
int x;
struct _open *next;
} *NODE;
And on my main function I declared this pointer:
NODE open = initOpen(size);
Here's the initOpen function:
NODE initOpen(int size) {
return (NODE)malloc(sizeof(struct _open)*size);
}
I this correct? can I access my array in the main function like: open[0] to open[9] ?
First of all, the way you are doing dynamically allocated array is wrong.
I'm not sure if you actually want the thing you wrote, which is linked list, or the thing you said, which is dynamically allocated array.
Below is how you should do dynamically allocated array. Hope it helps.
By doing so, you can add as many ints into the array as you want, before you run out of memory. And you can access the array using array notation but with a pointer first: darray->array[0]
Your linked list, however, can not be accessed with this syntax.
#include <stdio.h>
#include <stdlib.h>
#define INITSIZE 8
typedef struct dyarr{
int num;
int max;
int *array;
}arr;
arr* makeArr();
void add( arr*, int );
int main( int argc, char const *argv[] ){
int t;
arr* darray = makeArr();
while( scanf( "%d", &t ) != EOF ){
add( darray, t );
}
int i;
for( i = 0; i<darray->num; i++ ){
printf( "%d\n", darray->array[i] );
}
getchar();
return 0;
}
arr* makeArr(){
arr* A = malloc( sizeof( arr ) );
A->max = MAXSIZE;
A->num = 0;
A->array = malloc( sizeof( int )*A->max );
return A;
}
void add( arr* a, int i ){
if( a->num == a->max ){
a->max *= 2;
a->array = realloc( a->array, a->max );
}
a->array[a->num++] = i;
}
First of all, you should respect some conventions:
typedef struct node {
int x;
struct node *next;
} *nodePtr;
Second, what is the usage of the parameter size ?
According to me the right way to allocate a new nodePtr is:
nodePtr initNodePtr() {
return (nodePtr)malloc(sizeof(struct node));
}
Also dont forget to release memory after usage:
nodePtr node = initNodePtr();
...
...
free(node); //should be wrapped in a function to respect design.
To Create an array of structure, you should do the following:
typedef struct {
int x;
node* next;
} node;
int main() {
node* nodeArray = (node*)malloc(sizeof(node)*50); // 50 = size of your array
...
// do whatever you want
...
free(nodeArray);
}
Not tested, let me know if errors.

Allocate struct from function in C

I'm having issues writing a function that allocates a struct in C. Ideally, I want to have the function fill the fields of the struct with parameters passed into it.
I have defined the struct in my header file like so:
typedef struct {
char name[NAME_SIZE]; //Employee name
int birthyear; //Employee birthyear
int startyear; //Employee start year
} Employee;
And this is what I have for my function currently:
void make_employee(char _name, int birth_year, int start_year) {
Employee _name = {_name,birth_year,start_year}; //allocates struct with name
} /* end make_employee function */
Any advice on how to accomplish this?
The problem with your current code is that the struct your creating is created on the stack and will be cleaned up as soon as the function returns.
struct foo
{
int a;
int b;
};
struct foo* create_foo( int a, int b )
{
struct foo* newFoo = (struct foo*)malloc( sizeof( struct foo ) );
if( newFoo )
{
newFoo->a = a;
newFoo->b = b;
}
return newFoo;
}
This will get you a heap allocated object. Of course, you'll need a function to free that memory or this is a memory leak.
void destroy_foo( struct foo* obj )
{
if( obj )
free( obj );
}
void print_foo( struct foo* obj )
{
if( obj )
{
printf("foo->a = %d\n",obj->a);
printf("foo->b = %d\n",obj->b);
}
}
(btw, this style gets you part of the way toward an "object oriented" C. Add some function pointers to the struct (to get polymorphic behavior) and you have something interesting; though I'd argue for C++ at that point.)
You have to return a pointer allocated via malloc:
Employee* new_employee(char *_name, int birth_year, int start_year) {
struct Employee* ret = (struct Employee*)malloc(sizeof(struct Employee));
ret->name = _name;
ret->birth_year = birth_year;
ret->start_year = start_year;
return ret;
}
two more things: (1) you should make the struct definition of name a char* instead of char[NAME_SIZE]. Allocating a char array makes the struct much bigger and less flexible. All you really need is a char* anyway. And (2) change the function definition to char*.
Why does the make Employee return void? You need to return the Employee from the make_employee function!
Are you having trouble with the compiler complaining about the x = {a,...} syntax? Write it the long way then: Emp e; e.field1 = a; ...
Are you having weird overwriting / bogus numbers problems? If you allocate a struct in the function it will become invalid (and prone to being overwriten) as soon as the function returns! To go around this you either have to:
Return a copy of the struct (this is OK for small structs):
Employee make_emp(int a){
Emp emp; //Allocate temporary struct
emp.filed1 = a; //Initialize fields;
return emp; // Return a copy
}
Allocate the struct in the heap instead and deal with it through references (ie.: pointers) instead:
Employee* make_emp(int a){
Emp* emp = malloc(sizeof(Emp)); //Allocate the struct on the heap
//And get a reference to it
emp->filed1 = a; //Initialize it
return emp; //Return the reference
}
Don't forget to free() the Employee after you are done with it in this case!
Employee * make_employee(char *_name, int birth_year, int start_year)
{
Employee *employee;
if (employee = (struct Employee *)memalloc(sizeof(Employee)) == NULL)
{
return NULL;
}
else
{
strcpy(&(employee->name), _name);
employee->birthyear = birth_year;
employee->startyear = start_year;
return employee;
}
}

How to malloc "MyDef ** t" to a specific length, instead of "MyDef * t[5]" in C

A struct like the following works fine, I can use t after calling malloc(sizeof(mystruct)):
struct mystruct {
MyDef *t[5];
};
I want to be able to dynamically set the length of the array of MyDef, like the following:
struct mystruct {
MyDef **t;
int size;
};
What do I need to do additionally to malloc(sizeof(mystruct)) to get this to work, so I can do TestStruct->t[3] = something? Just getting a segmentation fault!
Thanks!
EDIT with code that causes seg fault, unless I'm blind this seems to be what the answers are so far:
#include <stdio.h>
typedef struct mydef {
int t;
int y;
int k;
} MyDef;
typedef struct mystruct {
MyDef **t;
int size;
} MyStruct;
int main(){
MyStruct *m;
if (m = (MyStruct *)malloc(sizeof(MyStruct)) == NULL)
return 0;
m->size = 11; //seg fault
if (m->t = malloc(m->size * sizeof(*m->t)) == NULL)
return 0;
return 0;
}
struct mystruct *s = malloc(sizeof(*s));
s->size = 5;
s->t = malloc(sizeof(*s->t) * s->size);
m = (MyStruct*)malloc(sizeof(MyStruct)) == NULL
What that does. Calls malloc, compares return of malloc to NULL. Then assigns the result of that comparison(a boolean value) to m.
The reason it does that is because '==' has a higher precedence than '='.
What you want:
if ( (m = (MyStruct *)malloc(sizeof(MyStruct))) == NULL)
...
if ( (m->t = malloc(m->size * sizeof(*m->t))) == NULL)
That happens because you do not allocate memory for array itself, only for pointer to this array.
So, first you have to allocate mystruct:
struct_instance = malloc(sizeof(mystruct));
and then you have to allocate memory for array of pointers to MyDef and initialize pointer in your struct
struct_instance->size = 123;
struct_instance->t = malloc(sizeof(MyDef*) * struct_instance->size);

Resources