allocate memory at a given pointer to memory

I tried to cast an int * to struct * .
It is not working exactly as i wanted it to be.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <bits/stdc++.h>
using namespace std;

struct my_malloc
{
	int is_available;
	int size;
};

void fun(int *p)
{
	struct my_malloc *mal = (struct my_malloc *)p;
	mal->is_available=1;
        mal->size = 100;
}

int main ()
{

	int p= 3;
	fun(&p);
	cout<<p<<endl;  // correct : 1
        
        int *ptr=&p;

	cout<<*ptr<<endl;  // correct : 1
	cout<<*(ptr+1)<<endl;// incorrect : produces 2686712 . Shouldn't it output 100 ?

	/*Uncommenting below lines gives runtime error . Why? */

	//struct my_malloc *mal_ptr = (struct my_malloc *)p;
	//cout<<mal_ptr->is_available<<endl;
	//cout<<mal_ptr->size<<endl;

 return 0;
}


Q1: What is the cause for this problem and how can it be corrected?
Q2: Can't we typecast ? I do it pretty much from void* to int* or int* to char* and everything works fine.

Why i am doing it?
I am my own malloc() function [Basic] . Since free() needs to know howw much bytes to free, so during malloc i will allocate memory = (sizeof(struct my_malloc) + user_asked_size ) and put a structure in front of the pointer to the 1st position of memory allocated.
Last edited on
1) Casting pointer to incompatible type invokes undefined behavior. Your program has no obligations to work as you expect. It might even format your hard drive and this will be behavior allowed by standard.
2) size of int and size of my_malloc are not equal. You are trying to access memory you do not own: another undefined behavior here.

In your case you are probably writing on stack which is instantly rewritten.

What is the cause for this problem and how can it be corrected?
Do npt do thing not allowed by language.

Can't we typecast ?
Yes, we can cast between compatible types. void* and char* are compatible with everything, but you cast from them to types incompatible with real type of underlying object is undefined too.
If you do something else and it works, it does not. It seems to work. Any change to the source code, enviroment or compiler can break it.

Also: you do not need to write struct everywhere in C++. my_malloc* mal = (my_malloc *)p; is valid and preferred c++.
You do not have to return anything from main. It returns 0 automaticaly.
Do not use c-casts. They are dangerous. Use c++ casts which would tell about illegality of your actions even before you run your program.
Last edited on
This is just plain wrong. What you're doing, is telling the computer to treat a block of memory the size and type of an int as though it were the type and size of my_malloc - the size of 2 ints. Where do you think that extra memory will come from? In your specific case, you are overwriting part of the stack in line 14.
Imagine you had another int variable, created on the stack right after p, say you had "int x = 0;" on line 21. When you execute line 14, you would have overwritten that variable.
This kind of code is a security loophole at best, but more likely you will suffer through many system crashes before this.

put a structure in front of the pointer to the 1st position of memory allocated.


You can't do that, that's memory you don't own. Also the logic is wrong, because you've already allocated the right size of memory, what you need to do is store the structure at the first location you allocated (assuming the rest of your scheme is okay).
Just use the structure, the right type, the right size. This use of int * and casting is unnecessary.

@tipaye ,
So how would you store structure at the first location , where void pointer to first location is given?
I still don't know what you're trying to do for sure, so forgive me if I'm answering the wrong question.

Programming in good old C, you'd do something like
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <string.h>
#include <stdlib.h>

typedef struct
{
	int is_available;
	int size;
} my_malloc;

void *do_my_malloc(size_t sz)
{
	my_malloc m = {sz, sz};
	void *my_mem = malloc(sizeof(m) + sz);
	// assert(NULL != my_mem);
	memcpy(my_mem, &m, sizeof(m));
	return my_mem;
}
Topic archived. No new replies allowed.