android.developer
android.developer

Reputation: 405

type casting void pointer and allocate memory

I have two structures:

typedef struct abc {
  unsigned int pref;
  unsigned int port;
  char *aRecordIp;
    int index;
    int count;
}abc_t;

typedef struct xyz {
        abc_t *ab;
        int index;
        int count;
}xyz_t;

and I would like to achieve the following

int Lookup (char *lookup,void *handle) {

*handle = (xyz_t *)malloc(sizeof(xyz_t *));
handle->ab = (abc_t *) malloc(sizeof(abc_t *));
//

}

I am trying to typecast void pointer to xyz_t basically.

Is this correct?

Upvotes: 0

Views: 3739

Answers (4)

Vivek S
Vivek S

Reputation: 1261

If you want to pass void *, here is the solution

int Lookup (char *lookup, void *handle) {

handle = malloc(sizeof(xyz_t));
((xyz_t *)handle)->ab = (abc_t *) malloc(sizeof(abc_t));
//

}

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753695

You are doing it wrong on multiple counts:

  1. You're trying to set a variable handle->ab, but handle is a void *, not a structure type pointer.
  2. You need to show your call, but there's likely to be problems — why do you think a void * argument is a good idea?
  3. You want to allocate structures, so the sizeof() operands should be xyz_t and not xyz_t *; repeat for abc_t.

You should probably use:

int Lookup(const char *lookup, xyz_t **handle)
{
    ...
    *handle = (xyz_t *)malloc(sizeof(xyz_t));
    (*handle)->ab = (abc_t *)malloc(sizeof(abc_t));
    ...
}

Don't forget to check the result of malloc().

There are those who will castigate you for using casts on malloc(). I won't. When I learned C (a long time ago, years before there was a C standard), on a machine where the int * value for an address was not the same bit pattern as the char * address for the same memory location, where malloc() had to be declared char *malloc() or all hell broke loose, the casts were necessary. But — and this is the major issue that people are concerned about — it is crucial that you compile with compiler options such that if you invoke a function without a prototype in scope, you will get a compilation error, or a warning that you will pay attention to. The concern is that if you do not have a declaration for malloc() in scope, you will get incorrect results from using the cast which the compiler would diagnose if you don't.

On the whole, though, I think you should separate your lookup code from your 'create xyz_t' code — your function is doing two jobs and it complicates the interface to your function.

xyz_t *Create_xyz(void);
int Lookup(const char *lookup, const xyz_t *handle);

Upvotes: 1

Israel Unterman
Israel Unterman

Reputation: 13510

I believe you want handle to hold a valid address of a xyz_t struct after the function call. Then you need to change the function signature and contents like so:

int Lookup (char *lookup, xyz_t **handle) {  // double indirection here

    *handle = (xyz_t *)malloc(sizeof(xyz_t));
    (*handle)->ab = (abc_t *) malloc(sizeof(abc_t));
}

And call it like this:

xyz_t *myhandle;
char lookup;  
Lookup(&lookup, &mynandle);

// now you can use it
myhandle->index ...

You will need to free the memory as well...

free(myhandle->ab);
free(myhandle);

Upvotes: 0

nullptr
nullptr

Reputation: 11058

While casting of a void* to any pointer type is correct, it is not necessary in C, and it is not recommended for malloc (e.g. see Do I cast the result of malloc? ).

Also, you should specify sizeof(xyz_t), not sieof(xyz_t*), otherwise you allocate memory enough only for pointer, not for the whole structure.

And of course you should assign a pointer to handle, not to *handle. And handle should be of proper pointer type (xyz_t*).

Oh, and if the question is about casting handle to xyz_t*, then you can do it like ((xyz_t*)handle)->ab.

I'd recommend reading a book before playing with pointers like that.

Upvotes: 0

Related Questions