void double pointer to other types - c

typedef struct
{
void **heapArr;
int last;
int capacity;
int (*compare) (void *arg1, void *arg2);
} HEAP;
int heap_Insert( HEAP *heap, void *dataPtr);
I was doing my assignment of insert data to heap with abstract data type.
I allocated memory to heap, but I got problem of inserting data to heap.
I can't find out how to make void double pointer to char or int arrays.
void *x=dataPtr;
heap->(*heapArr)=&x;
I tried this way but I got failed. How can I make void double pointer to other type?

Why heapArr is a double pointer ? I think a single pointer is enought...
typedef struct
{
void *heapArr;
int last;
int capacity;
int (*compare) (void *arg1, void *arg2);
} HEAP;
int heap_Insert( HEAP *heap, void *dataPtr){
heap->heapArr = dataPtr;
return 0;
}
int main(void){
char str[] = "hello";
HEAP heapString;
heap_Insert(&heapString, str);
char * str_get = heapString.heapArr;
printf("%s\r\n", str_get );
int val = 101;
HEAP heapInt;
heap_Insert(&heapInt, &val);
int * int_get = heapInt.heapArr;
printf("%i\r\n", *int_get);
}

If you want to convert void* to char*, then following is the method -
(say void *data)
char *a = (char*) data;
Similarly for double pointer,
char **a = (char**) heapArr;
Simply typecast will do the conversion. Please try and comment back what you see.

Related

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).

Malloc Member Array of Struct

I have a struct and an dynamic array inside the struct. I want to malloc this array but i don't really now how. I want that array void because i want the members of this array to be structs. As you can see i tried something but it doesn't really work
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct saf
{
int head;
void **stack;
int size;
}exp1;
void init(int n)
{
struct saf exp1->stack = malloc(n);
}
int main()
{
printf("Give size: ");
scanf("%d",&exp1.size);
init(exp1.size);
return 0;
}
exp1 isn't a pointer. Use
exp1.stack = malloc(n);
I believe you are looking for void *, e.g.,
void init (int n)
{
exp1->stack = malloc(sizeof(void *) * n);
}
You will have to cast it when you use it.
struct saf exp1.stack = malloc(n);
The above statement creates array of n memory locations and returns the void * pointer to the starting address. In this case stack should be single pointer i,e void *stack;
If you want stack to be a double pointer i,e void **stack then you should use
exp1.stack=malloc(sizeof(void *)*n);

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

Dynamic allocation of structs in C

I have a problem with dynamic memory allocation. Here is the code so please help.
#include <stdio.h>
int i;
typedef struct{
int A;
}node;
typedef struct Model
{
node *m;
} Model;
Model M;
void initialize(Model *a, int size)
{
a->m = (node*) malloc(size);
}
void model_init(Model *a, int len)
{
int i;
for (i=0;i<len;i++) a->m[i].A = 20;
}
int main()
{
initialize(&M ,10);
model_init(&M, 10);
for (i=0;i<10;i++) printf("%d\n",M.m[i].A);
}
I am trying to make a Model that has 10 nodes and I want to assign values to nodes in variable A. The printf shows (-1819044973, -1819044973, 14128019, 3969, 0, 0, 0 ...)
I just want it to say for example M.m[2].A=20
What am I doing wrong? please help.
TY
void initialize(Model *a, int size)
{
a->m = (node*) malloc(sizeof(node) *size); // NOTICE HERE!!!!
}
Your initialize function allocates a number of bytes then model_init later assumes that many node instances will be available. node is larger than 1 byte (at least sizeof(int) bytes) so you write beyond the end of allocated memory.
The easiest fix is to change initialize:
void initialize(Model *a, int elements)
{
a->m = malloc(elements * sizeof(node));
}
For more information on the fact that you don't have to cast malloc :
Do I cast the result of malloc?

using qsort() to sort pointers to structs containing strings

I'm not sure if this is possible to do with qsort because what I want to sort (array of pointers to struct) is not what I am comparing (strings).
Here is an abridged version of my program (assume that all the student data is in core before we call qsort() and n is the number of records to sort):
struct student {
char lname[NAMESIZE + 1];
char fname[NAMESIZE + 1];
short mid;
short final;
short hmwks;
};
int cmp(const void *, const void *);
int
main(int argc, char **argv)
{
int n;
struct student *data[MAX];
qsort(data, n, sizeof(struct student *), cmp);
return 0;
}
int
cmp(const void *p0, const void *p1)
{
return strcmp((*(struct student *) p0).lname,
(*(struct student *) p1).lname);
}
What will be passed to cmp() are struct student** parameters (in the guise of void*). So change cmp() like so:
int
cmp(const void *p0, const void *p1)
{
struct student* ps0 = *(struct student**) p0;
struct student* ps1 = *(struct student**) p1;
return strcmp( ps0->lname, ps1->lname);
}
It should be something like this:
int
cmp(const void *p0, const void *p1)
{
// pn is a pointer to an element of the array,
// so, it's effectively a pointer to a pointer to a struct.
// Therefore, we need to cast it appropriately to struct student **.
// To get a pointer to a struct from it, we dereference it once,
// hence the "*". Then we need to extract a pointer to the beginning
// of a string, hence the "->".
return strcmp((*(struct student **) p0)->lname,
(*(struct student **) p1)->lname);
}
The other answers are correct in everything but one little detail. I've just hit this, so i'll leave it here in case someone else finds themselves struggling with an extremely pedantic compiler.
qsort() comparator accepts two const void * parameters. Which means that when you dereference them to get pointers to your actual structs, you have to keep that const-ness. So, if you were to follow every single rule of C language, your code would look like this:
int
cmp(const void *p0, const void *p1)
{
const struct student* ps0 = *(const struct student* const*) p0;
const struct student* ps1 = *(const struct student* const*) p1;
return strcmp(ps0->lname, ps1->lname);
}
Note the "const pointer to const" construct - that's you telling the compiler that at no point your original pointers (p0 and p1) lose their const-ness - you first dereference them to a const * const *, and then dereference that to const *. If you simply use const **, that's a const * to * (non-const) pointer, which discards the original const-ness of const void *.

Resources