Store pointer address in malloced memory - c

This feels like a silly question, but I just can't work out a clean solution and can't find a similar question in the mass of other pointer related questions.
I have some dynamically allocated memory of unknown type and want to store a pointer inside it at the start. Dynamic memory returned by malloc should be suitably aligned so I don't think I have to worry about alignment when writing to the start of the allocated block.
This is my code, which works, but I'm representing a pointer as a 64-bit integer and want to do it in a more clean/portable way:
void *my_area = malloc(512);
void *my_pointer = get_my_pointer();
((long long *) my_area)[0] = (long long) my_pointer;

The cast to long long is just extra baggage. Cast to void * instead.
void *my_area = malloc(512);
void *my_pointer = get_my_pointer();
((void **) my_area)[0] = my_pointer;
(I assume that this is for some kind of freelist or the like, i.e., you don't need to use the structure at the same time.)

What will be found in my_area[0] is pointer to something, right ?
Then you can allocate my_area to be of type void **, which represent a pointer to a pointer containing memory area.
void **my_area = malloc(512 * sizeof(*my_area)); // alloc 512 pointer sized memory blocks
void *my_pointer = get_my_pointer();
my_area[0] = my_pointer;

Define a struct with internal array of 8 bytes. Replace all the long long type references with your custom struct. This way you will not depend on platform-specific size of long long. The struct will be 64 bits on all platforms(you can add #pragma pack if you worry about alignment )

Related

Why memory allocation for a structure in C works with any value given to malloc?

I tried to find the proper way to dynamically allocate memory for a structure that looks like this:
typedef struct myThread {
unsigned int threadId;
char threadPriority;
unsigned int timeSlice;
sem_t threadSem;
} myThread;
I remember, but I'm not sure, that, in some school paper, I saw that the proper way to allocate memory for this case is this one:
myThread *node = (myThread *)malloc(sizeof(myThread *));
I tried that and it worked, but I didn't understand why. Sizeof pointer for my architecture is 8 bytes, so by writing the instruction above, I'm allocating 8 bytes of continuous memory, not enough to hold the information needed in my structure. So I tried to allocate 1 byte of memory, like this:
myThread *node = (myThread *)malloc(1);
And it's still working.
I tried to find the answer for this behavior but I didn't succeed. Why is this working? Besides that, I have few more questions:
Which is the right way to dynamically allocate memory for a structure?
Is that cast necessary?
How is the structure stored in memory? I know that (*node).threadId is equivalent to node->threadId and this confuses me a bit because by dereferencing the pointer to the structure, I get the whole structure, and then I have to access a specific field. I was expecting to access fields knowing the address of the structure in this way: *(node) it's the value for the first element, *(node + sizeof(firstElement)) it's the value for the second and so on. I thought that accessing structure fields it's similar to accessing array values.
Thank you
Later Edit: Thank you for your answers, but I realized that I didn't explained myself properly. By saying that it works, I mean that it worked to store values in those specific fields of the structure and use them later. I tested that by filling up the fields and printing them afterwards. I wonder why is this working, why I can fill and work with fields of the structure for which I allocated just one byte of memory.
The below works in that they allocate memory - yet the wrong size.
myThread *node = (myThread *)malloc(sizeof(myThread *));// wrong size,s/b sizeof(myThread)
myThread *node = (myThread *)malloc(1); // wrong size
Why is this working?
When code attempts to save data to that address, the wrong size may or may not become apparent. It is undefined behavior (UB).
C is coding without training wheels. When code has UB like not allocating enough memory and using it, it does not have to fail, it might fail, now or later or next Tuesday.
myThread *node = (myThread *)malloc(1); // too small
node->timeSlice = 42; // undefined behavior
Which is the right way to dynamically allocate memory for a structure? #M.M
The below is easy to code right, review and maintain.
p = malloc(sizeof *p); //no cast, no type involved.
// or
number_of_elements = 1;
p = malloc(sizeof *p * number_of_elements);
// Robust code does error checking looking for out-of-memory
if (p == NULL) {
Handle_error();
}
Is that cast necessary?
No. Do I cast the result of malloc?
How is the structure stored in memory?
Each member followed by potential padding. It is implementation dependent.
unsigned int
maybe some padding
char
maybe some padding
unsigned int
maybe some padding
sem_t
maybe some padding
I wonder why is this working, why I can fill and work with fields of the structure for which I allocated just one byte of memory.
OP is looking for a reason why it works.
Perhaps memory allocation is done in chunks of 64-bytes or something exceeding sizeof *p so allocating 1 had same effect as sizeof *p.
Perhaps the later memory area now corrupted by code's use of scant allocation will manifest itself later.
Perhaps the allocater is a malevolent beast toying with OP, only to wipe out the hard drive next April 1. (Nefarious code often takes advantage of UB to infect systems - this is not so far-fetched)
Its all UB. Anything may happen.
Since memory allocation in C is quite error prone I always define macro functions NEW and NEW_ARRAY as in the example below. This makes memory allocation more safe and succinct.
#include <semaphore.h> /*POSIX*/
#include <stdio.h>
#include <stdlib.h>
#define NEW_ARRAY(ptr, n) \
{ \
(ptr) = malloc((sizeof (ptr)[0]) * (n)); \
if ((ptr) == NULL) { \
fprintf(stderr, "error: Memory exhausted\n"); \
exit(EXIT_FAILURE); \
} \
}
#define NEW(ptr) NEW_ARRAY((ptr), 1)
typedef struct myThread {
unsigned int threadId;
char threadPriority;
unsigned int timeSlice;
sem_t threadSem;
} myThread;
int main(void)
{
myThread *node;
myThread **nodes;
int nodesLen = 100;
NEW(node);
NEW_ARRAY(nodes, nodesLen);
/*...*/
free(nodes);
free(node);
return 0;
}
malloc reserves memory for you to use.
When you attempt to use more memory than you requested, several results are possible, including:
Your program accesses memory it should not, but nothing breaks.
Your program accesses memory it should not, and this damages other data that your program needs, so your program fails.
Your program attempts to access memory that is not mapped in its virtual address space, and a trap is caused.
Optimization by the compiler transforms your program in an unexpected way, and strange errors occur.
Thus, it would not be surprising either that your program appears to work when you fail to allocate enough memory or that your program breaks when you fail to allocate enough memory.
Which is the right way to dynamically allocate memory for a structure?
Good code is myThread *node = malloc(sizeof *node);.
Is that cast necessary?
No, not in C.
How is the structure stored in memory? I know that (*node).threadId is equivalent to node->threadId and this confuses me a bit because by dereferencing the pointer to the structure, I get the whole structure, and then I have to access a specific field. I was expecting to access fields knowing the address of the structure in this way: *(node) it's the value for the first element, *(node + sizeof(firstElement)) it's the value for the second and so on. I thought that accessing structure fields it's similar to accessing array values.
The structure is stored in memory as a sequence of bytes, as all objects in C are. You do not need to do any byte or pointer calculations because the compiler does it for you. When you write node->timeSlice, for example, the compiler takes the pointer node, adds the offset to the member timeSlice, and uses the result to access the memory where the member timeSlice is stored.
you do not allocate the right size doing
myThread *node = (myThread *)malloc(sizeof(myThread *));
the right way can be for instance
myThread *node = (myThread *)malloc(sizeof(myThread));
and the cast is useless so finally
myThread *node = malloc(sizeof(myThread));
or as said in remarks to your question
myThread *node = malloc(sizeof(*node));
The reason is you allocate a myThread not a pointer to, so the size to allocate is the size of myThread
If you allocate sizeof(myThread *) that means you want a myThread ** rather than a myThread *
I know that (*node).threadId is equivalent to node->threadI
yes, -> dereference while . does not
Having myThread node; to access the field threadId you do node.threadId, but having a pointer to you need to deference whatever the way
Later Edit: ...
Not allocating enough when you access out of the allocated block the behavior is undefined, that means anything can happen, including nothing bad visible immediately

Struct pointer syntax confusion

Hi i'm relatively new to c and was wondering if anyone could explain what exactly i'm doing with the following code.
I have a struct:
typedef struct free_list_header {
u_int32_t magic; // ought to contain MAGIC_FREE
vsize_t size; // # bytes in this block (including header)
vlink_t next; // memory[] index of next free block
vlink_t prev; // memory[] index of previous free block
} free_header_t;
and I'm initialising it within a function using the following...
void vlad_init(u_int32_t size)
{
int sizePow2 = pow(2, ceil(log(size)/log(2)));
memory = malloc(sizePow2*sizeof(char));
memory_size = sizePow2;
strategy = BEST_FIT;
free_header_t *freeHeader = (free_header_t*)memory;
freeHeader->magic = MAGIC_FREE; // the unique value
freeHeader->size = memory_size; // amount we malloc'd
freeHeader->next = 0; // position of next free block
freeHeader->prev = 0; // position of prev free block
free_list_ptr = 0;
}
my question is what exactly am i doing here and why is it necessary?
free_header_t *freeHeader = (free_header_t*)memory;
So... i'm declaring a new struct by pointing to it named "freeHeader"? and that is a pointer to it in the memory i have allocated? So this is a way of putting the struct into the malloc'd area to access it out of the function in which im initializing it?
Malloc returns a void pointer (type void*). This means it returns a pointer to a memory address and that pointer is not pointing to any specific type. So after the line:
memory = malloc(sizePow2*sizeof(char)); //sizePow2 is n bytes to allocate
memory is a pointer of type (void *).
free_header_t *freeHeader = (free_header_t*)memory;
On the left hand side here you are creating a pointer named freeHeader that points to a memory address containing something of type free_header_t
Since you explicitly said this pointer is pointing to an address of type free_header_t to you are casting the other side (currently of type void *) to match it as free_header_t *.
NOTE in C, this works but is not necessary. The compiler will automatically cast a void * to whatever type you need. However writing code like this is good practice, in C++ you need to explicitly do this.
free_header_t * freeHeader = (free_header_t*)memory;
you declared a pointer (not an actual struct) to free_header_t struct named freeHeader and you assigned it the value of the pointer named memory. since memory is a pointer to char and yours is a pointer to something else, you used casting.
You currently have only a pointer to an allocated area (of size sizePow2*sizeof(char) - note that the size of the struct should be less or equal to the size of the allocated memory).
Your code is essentially equivalent to:
free_header_t *freeHeader = malloc(sizePow2 * sizeof(char));
It's allocating a block of memory that contains sizePow2 bytes, and then using that as the address of a free_list_header structure.
The reason it uses the memory variable is because some other code is going to use the next and prev members as indexes into that block of memory. As the name implies, this structure just contains the data at the beginning of the memory block, the rest of the memory is managed with other structures.
memory = malloc(sizePow2*sizeof(char));
You are allocating some memory here. It would be good to just use
memory = malloc(sizeof(struct free_list_header));
to store an object of the structure.
free_header_t *freeHeader = (free_header_t*)memory;
Here you are declaring a pointer which would point to memory allocated earlier. You did not technically declare an object of the structure. And you are not putting the structure in to malloc-ed area, you are instead treating the malloc-ed area as an object of the structure.
free_header_t freeHeader = {0}; would be declaring an object of the structure.
Every time you call malloc() function, the operating system returns you a single memory address. When you cast this pointer to a specific type you tell to compiler that every element stored in the memory allocated will consume the size of the specified type and this get the things easier.
Let suppose that you declare a uint64_t* and the size of allocation it's 100 times the size of uint64_t, so you're asking for 800 bytes for the operating system, once the uint64_t takes 8 bytes. If you do not cast this pointer, every time you increase the address with your_variable++ your program will skip only one byte and you will get in the "middle of the number and will get a weird value", but if you cast your pointer to a uint64_t and increase the address with your_variable++ your program will skip 8 bytes, going directly to the next number.
In your example, you're telling to the operating system that your pointer will store types of free_header_t. You're not obligated to do it, but it is a very good practice.
And yes, if you return this address to another function, the other function can change the value stored in this memory area easily.
Hope it helps!

Generic function for malloc to accept all data type

Given a function as(it can use malloc() internally)as void* function_ptr(void *ptr, int size);
where void *ptr is a void pointer and size is the number and in return it should allocate the memory depending on the data type. For int, it should allocate 4*size(considering 32 bit) and for char 1*size.
for example,
for integer data type, function_ptr((void *)some_int_ptr, 10 )
it should allocate 10 *4(32 bit) = 40 bytes and
function_ptr((void *)some_char_ptr, 10 ), 10 bytes should be allocated
Question is how can we typecast void * to int/char/double pointer as function does not know as which datatype was typecast to void* ?
It was a interview question, i tried answering as sending 1 more parameter which mentions the data type and hence we can allocate and assign memory but was not accepted as
void* function_ptr(void *ptr, int size, int data_type);
You can't know the data type from inside the function, as there is no type information available. There are two options:
1) Either make the function work on the size in bytes, then it doesn't need to know the type. Perhaps this was actually what the interviewer meant?
2) Rewrite the function so that it includes type information somewhere.
There are also bad alternatives such as using global variables or replacing the function with a wrapper macro, but neither is recommended.

Difference between two malloc definition of a struct

I would like to know if there's a real difference between this:
c = (struct_t *) malloc(sizeof(struct_t));
and this
c = malloc(sizeof(struct_t *));
Besides avoid the cast, is the compiler takes any advantage in the second form respect the first? Or the two ways are completely the same and is just a "aesthetical" question ?
The first allocates sizeof(struct_t) bytes, the second sizeof(struct_t*) bytes.
Apart from that, there is no difference in what malloc does, whether you cast the result or not. Casting the result makes the code acceptable to C++ compilers, but it can hide the mistake of not including stdlib.h, therefore it is widely preferred to not cast the result in C.
The two are totally different. The first allocates an instance of the struct, whereas the second allocates a pointer to the struct.
In general, they won't even allocate the same number of bytes.
No, they are not the same. The latter allocates 4 or 8 bytes of space for a pointer to struct, the first allocates enough space for the struct it self.
When sizeof(struct_t) is small enough, and when the malloc allocates actually more than requested, the user may not see the difference.
Two forms are different. They both allocate memory, but with different amounts.
General rule is as follows:
when allocating type T, the result of malloc shall be casted to T*.
void sample1()
{
struct pollfd *pfd = (struct pollfd*)malloc(sizeof(struct pollfd));
// pfd is points to a memory with a size of struct pollfd
...
free(pfd);
}
void sample2()
{
struct pollfd *pfd = (struct pollfd*)malloc(sizeof(*pfd));
// same as above, but uses variable type instead
free(pfd);
}
If you specify incorrect type in malloc argument, generally that will lead to buffer overrun problems:
void sample3()
{
struct x *px= (struct x*)malloc(sizeof(struct x*));
x->field = 5; //<< error, as allocated only 4 or 8 bytes depending on pointer size
}
Both are different.
Usually malloc returns (void*). So you want to typecast void* to (struct_t*).

Declaring array of voids

I'm writing a program that copies files. I've used a buffer in order to store the information that the read() function provides and then give this data to the write() function. I've used this declaration:
static void buffer[BUFFER_SIZE];
The problem is that I get the the error error: declaration of ‘buffer’ as array of voids.
I don't understand why declaring an array of void is an error. How can I declare a block of memory without a specific type?
I don't understand why declaring an array of void is an error.
The technical reason you cannot declare an array-of-void is that void is an incomplete type that cannot be completed. The size of array elements must be known but the void type has no size. Note that you are similarly unable to declare a void object, as in
void foo;
Note that a pointer-to-void has a specific size, which is why
void *foo;
is valid, as well as sizeof(foo), but sizeof(*foo) would be invalid.
How can I declare a block of memory without a specific type?
For generic memory buffers, use an array of plain char or unsigned char (or even uint8_t). I usually prefer plain char when I need to pass pointers to the str* family of functions where array of unsigned char would lead to diagnostics about incompatible pointers.
Use an array of char or unsigned char instead.
When declaring an array, the compiler must know the size of the array.
The void type has no size. So compiler report error.
This is how you do it, although it is not an array of voids as you may have wanted, it is an array of void pointers; in each cell of this void pointer you can assign ANYTHING.
If you wish to store a variable, you simply cast it to (void*), here is an example:
void *XPoint[5] = { 0 };
XPoint[0] = (void*)5; // int
XPoint[1] = "Olololo!"; // char*
XPoint[2] = (void*)'x'; // char
XPoint[3] = (void*)structA.nNum; // struct int
You also can declare void pointer:
void* buffer;
// just pointers for simple work with allocated piece of memory
char* chBuf;
long* intBuf;
then use malloc() for this pointer and work with this piece of memory like with an any array (char, short, long, float, double or your own type). Don't forget to use free() to avoid memory leak in this case.
buffer = malloc (BUFFER_SIZE);
if (buffer==NULL)
exit (1);
// init our buffers
chBuf=(*char)buffer;
intBuf=(*long)buffer;

Resources