1

I'm working with pointers to structs and have the following set up which has been working.

/* Initialized. */
struct base { ... };  
struct base **db;
db = malloc( base_max * sizeof *db );

/* When a new struct base is required. */
db[ i ] = malloc( sizeof( struct base ) );

Now, if possible, although not really essential, I'd like only db[0] to point to a different struct, struct mem { ... }. Is this possible and what is the proper way to do so?

I figured I can set db[0] = malloc( sizeof( struct mem ) ); but db is already declared to point to a pointer pointing to a struct base; and the memory allocation of db is based on that also.

I'm confused because I read pointers must have a type or pointer arithmetic won't work properly; but I also read you don't have to cast the pointers from malloc even though it returns void pointers.


Regarding the duplicate question, although it discusses void type it doesn't answer my question of how to accomplish this or the risks of it. The comment by @4386427 appears to point to the real issue to be considered which isn't addressed in the other question or the one answer to this one. Thank you.

Gary
  • 2,393
  • 12
  • 31
  • There is nothing wrong with `db[0] = malloc( sizeof( struct mem));` It's legal.... Whether you'll get into problems depends on how you use `db[0]` later on. Since you didn't post that code, we can't tell – Support Ukraine Dec 31 '20 at 08:32
  • I believe that the question implicitly discusses pointers to void. If you do not agree let me know, but based on that assumption I propose the following duplicate: – Yunnosch Dec 31 '20 at 08:33
  • Does this answer your question? [How to verify if a void pointer (void \*) is one of two data types?](https://stackoverflow.com/questions/58280538/how-to-verify-if-a-void-pointer-void-is-one-of-two-data-types) – Yunnosch Dec 31 '20 at 08:33
  • You could also use unions of the two types – stark Dec 31 '20 at 12:30
  • @4386427 Thank you, that makes the most sense. `db[i>0]` is a set of pointers to a sqlite database, a set of prepared statements, a char array of directory path, and then a regular int(no pointer). `db[0]` is an in-memory database and has fewer prepared statements and no path. Probably best to just keep `db[0]` separate and out of the array of pointers and avoid risk of an unexpected error elsewhere. Out of curiosity, would `db[0] + sizeof(struct mem)` point to `db[1]`, and `db[1] + sizeof(struct base)` point to `db[2`], as can be done with character arrays? Thank you. – Gary Dec 31 '20 at 21:55
  • If you intend `db[n]` to be pointers to various unrelated structs, consider making `db` be `void**` so that it is less confusing to the reader – M.M Dec 31 '20 at 22:34
  • I meant *db[i], not db[i] since it points to a pointer. – Gary Jan 01 '21 at 21:18
  • @M.M Thank you. I thought about trying that before posting this question but couldn't figure out what to do with `struct base **db` . I get a bit confused because `db `points to a pointer to a `struct`. Can it be just `void** db` and then `malloc` will set the type when `db[i] = malloc( sizeof( struct ? ))`? – Gary Jan 01 '21 at 21:43
  • `malloc` doesn't set the type of anything; type is set by using the space . Of course you also need some way of remembering or knowing what type of data you are storing in each allocation . – M.M Jan 01 '21 at 23:13

1 Answers1

-1

In majority of the architecture, the size of a pointer (to any type) is constant, and any pointer type will generally occupy the same amount of memory.

Unless you're on some really uncommon hardware/platform, you can assign db[0] with any pointer returned by malloc() using a different structure type used for sizing calculation altogether.

 db[0] = malloc( sizeof( struct mem ));

should do good, you just need to worry about memory leak, as you'll be overwriting the previous memory location returned by malloc().

However, since you're storing a pointer to memory of a differnt type, while using db[0], i.e., dereferencing it, you need to cast it to the proper pointer type (i.e., struct mem*) before you can use the pointer to access /operate based on the struct mem type.

That said,

I'm confused because I read pointers must have a type or pointer arithmetic won't work properly;

That's true

but I also read you don't have to cast the pointers from malloc even though it returns void pointers.

Also true, as when you assign the pointer to a variable of a certain type (other than void), the conversion is implicit. You can use that variable to perform pointer arithmetic.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • 1
    `void *` can be converted to `struct foo *` on any platform. Also the space allocated by `malloc` is untyped until first written . – M.M Dec 31 '20 at 22:33