Access function pointer defined in a structure? - c

Write a program to access the function "foo" using the structure structure2.
typedef struct
{
int *a;
char (*fptr)(char*);
}structure1;
typedef struct
{
int x;
structure1 *ptr;
}structure2;
char foo(char * c)
{
---
---
---
}

structure2 *s2 = (structure2*)malloc(sizeof(structure2));
s2->ptr = (structure1*)malloc(sizeof(structure1));
s2->ptr->fptr = foo;
char x = 'a';
s2->ptr->fptr(&x);

Create an object of type structure2
Assign to it the address of an object of type structure1 (this can be done in quite a few ways)
Assign foo to the above allocated structure1 object's fptr member
Call foo using:
structure2 s2;
// allocate
char c = 42;
s2.ptr->fptr(&c); // if this
Example:
typedef struct
{
int *a;
char (*fptr)(char*);
}structure1;
typedef struct
{
int x;
structure1 *ptr;
}structure2;
char foo(char * c)
{
return 'c';
}
int main()
{
structure1 s1;
structure2 s2;
s1.fptr = foo;
s2.ptr = &s1;
char c = 'c';
printf("%c\n", s2.ptr->fptr(&c));
return 0;
}

Related

How to sort an array of structs using qsort

It's supposed to sort students in alphabetical order by their last names. I tried to do it with
qsort, but it doesn't work.
struct student {
char name[30];
char lastName[30];
char grades[30][5];
int numberOfGrades;
};
int compare(const void *a, const void *b) {
struct group *s1 = (struct group *)a;
struct group *s2 = (struct group *)b;
return strcmp(s1->lastName, s2->lastName);
}
int main()
{
struct student group[30];
group[0].lastName = "Malaska";
group[1].lastName = "Kowalski";
group[2].lastName = "Adamczyk";
group[3].lastName = "Bakiewicz";
int numberOfStudents = 4;
qsort(group, numberOfStudents, sizeof(group), compare);
}
The following is an adaptation of your code with corrections and comments:
struct student {
char name[30];
char lastName[30];
char grades[30][5];
int numberOfGrades;
};
//Note, error incomplete type occurs
//when using `struct group *s1 = (struct group *)a;`
//will replace with `struct student`
int compare(const void *a, const void *b) {
const struct student *s1 = (struct student *)a;
const struct student *s2 = (struct student *)b;
return strcmp(s1->lastName, s2->lastName);
}
int main()
{
struct student group[30];//local scope, will not be recognized in 'compare()'
strcpy(group[0].lastName, "Malaska");//string assignments need to use strcpy or similar, not =
strcpy(group[1].lastName, "Kowalski");
strcpy(group[2].lastName, "Adamczyk");
strcpy(group[3].lastName, "Bakiewicz");
int numberOfStudents = 4;
//sending correct size of each element
qsort(group, numberOfStudents, sizeof(group[0]), compare);
// ^^^^^^^^^^^^^^^^^
}
The following is also an adaptation of your code, but with some additional changes to construct that if in scope of what you are learning, should provide a few more examples of readability, use of scope, use of typedef, and dynamic memory allocation and freeing...
typedef struct { //use of `typedef struct {` rather than 'struct name {`
char name[30];
char lastName[30];
char grades[30][5];
int numberOfGrades;
}student_s; //new type, can be used in place of `struct student` anywhere.
int compare(const void *a, const void *b) {
const student_s *s1 = (student_s *)a;
const student_s *s2 = (student_s *)b;
return strcmp(s1->lastName, s2->lastName);
}
int main()
{
int numberOfStudents = 4;//moved to top so can use group
//to properly size instances of group
//dynamic memory allocation, and clean up at bottom
student_s *group = calloc(numberOfStudents, sizeof *group);
if(group)//test here to ensure success
{
strcpy(group[0].lastName, "Malaska");
strcpy(group[1].lastName, "Kowalski");
strcpy(group[2].lastName, "Adamczyk");
strcpy(group[3].lastName, "Bakiewicz");
qsort(group, numberOfStudents, sizeof(group[0]), compare);
//... more code as necessary
//when finished with 'group', free it.
free(group);
}
}

Assigning int array to a int pointer

I want to assign value of an array to a pointer or need a better way to do the below operation .
I have a structure
struct ver{
int *a;
int *b
int *c;
}
struct Versions{
int ver1[3];
int ver2[3];
int ver3[9];
}
static const Versions versionsinfo[] {
"001234",
{0,18,0},
"000000"
};
static Temp_Data;
Versions * GetVersions() {
Versions * pt = NULL;
memcpy(&Temp_Data,&versionsinfo[1]);
pt = &Temp_Data;
return pt ;
}
struct Versions *pointer;
pointer = GetVersions();
struct ver *newVer;
newVer->a= pointer->ver1;
newVer->b= pointer->ver2;
newVer->c= pointer->ver3;
I want to assign the value of Ver1 to a member of struct ver , either a, b or c.
can anyone please let me know if this is possible in C.
Hope this helps
struct ver
{
int *a;
int *b;
int *c;
};
int Ver1[3] = {1,2,3};
int Ver2[3] = {1,2,3};;
int Ver3[9];
struct ver *newVer;
int main()
{
struct ver newV;/*the memory for struct var is allocated in main */
newVer = (struct ver *)malloc(sizeof(struct ver));/*memory allocated in heap*/
newV.a = Ver1;/*OR newVar.a = &Ver1[0];*/
newV.b = Ver2;
newV.c = Ver3;
printf("newV->a[0] is %d", newV.a[0]);
/*OR*/
newVer->a = Ver1;
newVer->b = Ver2;
newVer->c = Ver3;
printf("\nnewVar->a[1] is %d", newVer->a[1]);
free(newVer);
return 0;
}
Well,
int Ver1[3];
int Ver2[9];
int Ver3[9];
They are initializing arrays of type int. So if you want to get those numbers (which are the sizes of the arrays in the above) you need to do
int Ver1 = 3;
int Ver2 = 9;
int Ver3 = 9;
The allocate some memory for the pointer
struct ver *newVer = malloc(sizeof(newVer));
and then put the values in the struct
newVer[0].a = Ver1;
newVer[0].b = Ver2;
newVer[0].c = Ver3;

struct assignment: segment fault 11

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
union value {
long long i;
unsigned long long u;
double d;
long double ld;
void *p;
void (*g) ();
};
struct foo {
struct {
union value max;
union value min;
}limits;
};
struct bucket_info {
void *p; // free position
void *limit; // end position
struct bucket_info *next; // next bucket
};
#define NODES 8192
void * my_malloc(size_t size)
{
void *p = malloc(size);
if (!p)
exit(1);
memset(p, 0, size);
return p;
}
void * alloc_bucket(size_t size)
{
struct bucket_info *pb;
pb = my_malloc(sizeof(struct bucket_info) + size);
pb->p = pb + 1;
pb->limit = (char *)pb->p + size;
return pb;
}
void * alloc_for_size(struct bucket_info *s, size_t size)
{
void *ret;
while (s->next)
s = s->next;
if ((char *)s->p + size > (char *)s->limit) {
struct bucket_info *pb = alloc_bucket(size * NODES);
s->next = pb;
s = pb;
}
ret = s->p;
s->p = (char *)s->p + size;
return ret;
}
static void * alloc_node(struct bucket_info **s, size_t size)
{
if (!*s)
*s = alloc_bucket(size * NODES);
return alloc_for_size(*s, size);
}
static struct bucket_info *foo_info;
void * alloc_foo_node()
{
void *ret = alloc_node(&foo_info, sizeof(struct foo));
return ret;
}
struct foo * new_foo()
{
return alloc_foo_node();
}
void test(int t, struct foo *foo1)
{
struct foo *foo2 = new_foo();
// Crash at this line
*foo2 = *foo1;
// comment this switch statement, it works. why?
switch (t) {
case 1:
break;
default:
break;
}
}
int main(int argc, const char * argv[]) {
struct foo *foo1 = new_foo();
test(10, foo1);
return 0;
}
Above is the complete code. And I've compiled it with clang, got a 'Segment Fault 11' at line:
*foo2 = *foo1;
Then, change this line to:
memcpy(foo2, foo1, sizeof(struct Foo));
It works.
Then I've tried compiled these two cases with gcc, there is no problem.
The value returned by alloc_foo_node may not be correctly aligned for struct foo.
On my system, printing _Alignof(struct foo) gives 16, but the pointers foo1 and foo2 are not multiples of 16.
So it causes undefined behaviour to convert the unaligned result of alloc_foo_node to have type struct foo *.
To fix this you have to muck around a lot more with your allocation code, to make sure that it only ever hands out space that is on the correct boundary for struct foo. You could use max_align_t to help with this (it is defined so that _Alignof(max_align_t) is the biggest possible alignment required).

type casting void pointer to struct type

How do I type cast a void pointer to a struct array? Here is my code:
typedef struct{
int a;
double b;
} myStruct;
void Func1(void * Array1);
int main(){
myStruct S1[5];
S1[0].a = 1;
S1[0].b = 2.3;
S1[1].a = 2;
S1[1].b = 3.4;
Func1(S1);
return 0;
}
void Func1(void * Array1){
myStruct S2[5];
S2[0] = (myStruct *)Array1[0];
}
I get compile errors in Func1 for assigning S2[0]. How do I typecast the Array1 correctly?
[] operator has a higher precedence that a (cast) operator. Thus you have to use additional parenthesis:
S2[0] = ((myStruct *)Array1)[0];
or use a pointer:
myStruct* a = Array1 ;
S2[0] = a[0];

struct pointer as parameter and return

I have a function which takes a struct pointers as parameter and returns it.ın the function i want another function fill up the memory pointerd by the pointer.my code is
struct my_struct{
unsigned char** ps;
unsigned long* pl;
};
struct* function(struct* param){
another_func(param->ps,param->pl)//function takes pointers as parameters and fills them up
return param;
}
int main{
my_struct *p;
p=function(p);
}
//definiton of another func is;
void another_func(unsigned char**,unsigned long * ){...}
EDIT:it gives the error access violation
From what you have posted so far try instead:
typedef struct my_struct
{
unsigned char** ps;
unsigned long* pl;
} my_struct;
void another_func(unsigned char**,unsigned long * ) {...}
my_struct* function(my_struct* param)
{
another_func(param->ps,param->pl)
return param;
}
int main()
{
my_struct *p;
my_struct q = {NULL,NULL};
unsigned long pl = 10;
q.ps = malloc( pl * sizeof(char*) );
q.pl = &pl;
p=function(&q);
return 0;
}
edited after chat

Resources