Click here to Skip to main content
15,887,214 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
This one is mostly a simple question.
Malloc funtions return the address to the memory a user has defined (the size of the memory).

So if it gives the address, it acts like &x when we have int x = 5 in which malloc is like &x and its access to that memory is like int x = 5.

What I have tried:

Fistly, I've checked if there is something like Function pointer. And there it was!
C
#include <stdio.h> 
// A normal function with an int parameter 
// and void return type 
void fun(int a) 
{ 
    printf("Value of a is %d\n", a); 
} 
  
int main() 
{ 
    // fun_ptr is a pointer to function fun()  
    void (*fun_ptr)(int) = &fun; 
  
    /* The above line is equivalent of following two 
       void (*fun_ptr)(int); 
       fun_ptr = &fun;  
    */
  
    // Invoking fun() using fun_ptr 
    (*fun_ptr)(10); 
  
    return 0; 
} 

And this:
C
#include <stdio.h> 
// A normal function with an int parameter 
// and void return type 
void fun(int a) 
{ 
    printf("Value of a is %d\n", a); 
} 
  
int main() 
{  
    void (*fun_ptr)(int) = fun;  // & removed 
  
    fun_ptr(10);  // * removed 
  
    return 0; 
}

It says that Function pointer works differently that it points to a code not an address.

Although in the second example, what if I use (*fun_ptr)(10); ?
So is (int *) malloc is the same as void (*fun_ptr)(int) = &fun;? By same, I mean is it a Function pointer? Which would be weird on the other hand because if I write (int **)malloc, then it returns the address to a pointer in (int *) malloc, it returns the address to the memory.
Posted
Updated 24-Oct-23 11:11am
v2

No. Malloc always returns the same type: void * - a pointer to a void.
You can then recast that safely to any type of data pointer you need, it is literally just an address in the data memory area that is allocated dynamically.
Function pointers are different: they only ever point to addresses in the code memory area (which is normally write protected) and the addresses you put in them are not dynamically allocated - they are fixed at link time which is the last process in building an EXE file, and entirely separate from compilation. You cannot cast a function address (or a function pointer) unless the parameters are identical (ie.e you can cast it's return type, but not it's parameter list or types); nor can you do any useful arithmetic with them because functions do not have a defined size at compile time, unlike data types which must.

You can store function addresses in memory, even in blocks allocated by malloc - and you can manipulate them since there have a defined size at compile time, but you can't do anything fancy with the pointers themselves (and you should be very wary of code that does as it's amazingly easy to crash your app if you play with functions pointers or addresses).

Seriously, stop playing and finding random bits and pieces on the internet - get a book or course on C and follow that. Your recent questions show that you really don't understand what is going on, even though I suspect you think you do!
 
Share this answer
 
Comments
Member 16116753 20-Oct-23 11:59am    
Sorry if my questions seems random.
I in school encounter with these type of situations so when I encounter something new I try to find something similar on the website because I don't know how to call this new thing.

Like I showed with void (*fun_ptr)(int) = fun; it look very similar to (int *) malloc() both of them are functions and both of them have pointer * but differently written ? I don't know is there a difference if I write (int *) and int (*) ????

I also sometimes comeup with the answear to the question after sometime reading the forum.
And you are perfectly right I don't really much grasp sometimes simple thing which I am sorry for ... I just find in a code something I don't understand and try to find that information. And finding an info usually give me new questions so I didn't know it is random.

void * - a pointer to a void. What does it mean what can I compare it to ? And what I can compare malloc to from simple examples ?
Function pointers you've told, I don't quite get it. They have pointer but this pointer is different from other pointers so &fun in which fun is a function is invalid ?

Again sorry for annoying you everyone I just try to compare new stuff with old stuff because these addresses and pointers are mixing up. Like malloc it has a (int *) which indicates that it is a pointer like int * ptr. But it returns an address which is not a pointer ;>
The malloc function only ever returns an address of a block of memory, nothing less nothing more. Although it will return NULL if there is no space available. And yes, a function pointer is always the address of the code, so (like an array name) you do not need the & (addressof operator) on it. As to your question, "(int *) malloc is the same as void (*fun_ptr)(int) = &fun;"; no it is not, and the question really makes no sense. You seem to be tying yourelf in knots over pointers and making it far more complicated than it needs to be. As OriginalGriff has already suggested, get yourself a book on C and learn it properly rather than wasting your time with these questions. The best book on the subject is "The C Programming Language" by Kernighan & Richie.
 
Share this answer
 
Comments
Member 16116753 20-Oct-23 11:26am    
I'm sometimes basing my questions from the books.
I also watch tutorials that starts from the beggining and step by step shows new stuff that also is connected to the last lessons. So I was stuck with pointers and how do they work. Maybe questions are pointless but then what quesitons should I ask ? I am stuck with the tutorials or information from books on website
Richard MacCutchan 20-Oct-23 11:48am    
The book I suggested explains pointers in clear detail. And if you work through the book from start to finish, practicing all the suggested code, you will find it easier to understand. And I would avoid videos, as so many are of poor quality.
Member 16116753 20-Oct-23 12:07pm    
Hmm I will give it a try, so far I was following "Understanding and Using C Pointers".
But I usually have a problem with pointers that I compare new stuff with old stuff like I showed with malloc because they look similar if not the same but one has (int *) function and the other is int (*function). I have a feeling with new book I will have the same because I very often compare new stuff because mallox acts like &x and the content of malloc is like int x, which is weird because malloc has next to it (int *)
k5054 20-Oct-23 12:32pm    
You don't even need to buy it: https://colorcomputerarchive.com/repo/Documents/Books/The%20C%20Programming%20Language%20(Kernighan%20Ritchie).pdf
This book is THE reference for learning C, IMO. I'ts what I used to get started, back in the pre-ANSI days. I'm sure its the go-to book for just about everyone, except perhaps Kernighan and Ritchie themselves
Member 16116753 20-Oct-23 15:40pm    
This book contains these type of dilemma like my questions ? And what if doesn't ? Should I ask here or will it be treated like random question ?
The previous solutions have given appropriate answers. Here's a macro I use when I have to wade into the malloc/free world. It does two main things - it takes care of the casting needed (since malloc returns a void pointer) and it uses calloc so that the memory allocated is cleared to zeros. Incidentally, that's what the C in the name refers to. Anyway, here it is :
C
#define Allocate(count,type)  (type *)calloc(count,sizeof(type));
and here is how it is used :
C
int * pIntegers = Allocate( 42, int );
In contrast, here is how that would look without the macro :
C
int * pIntegers = (int *)calloc( 42, sizeof( int ) );
As has been stated, calloc and malloc return a void pointer so that must be cast to the type that is needed.
 
Share this answer
 
Comments
Member 16116753 20-Oct-23 13:26pm    
Maybe different question. What does it mean it returns a void pointer. If I had int *ptr then I guess ptr is a integer pointer and *ptr is the value I guess.

It is still very weird because because it's like a pointer points to the content of another pointer like this :

int *p;
int *x;
p = x;

Usually I see double pointers like these :

int **p;
int *x;
p = &x;

So I thought the first one is incorrect or rather why then use this int *x when this int will have no meaning because the shift from first example is defined by int *p not int *x. Or in other way because my english might be very bad. From first example if I had

int *p;
char *x;
p = x

and shifter by 1 p + 1 it shift by 4 byte no matter what the x is if it's char or int.
If i had the second example it would have also any matter because the pointer is 8 byte big so shifting it will be correct anytime p = &x; and typing p + 1 will shift by 8 bytes

And so this also means that the malloc has the addres of that pointer so it indicates that &malloc is there because malloc is a pointer.

ehhhh
OriginalGriff 20-Oct-23 14:11pm    
It means that the pointer it returns can't be used on either side of an assignment operator unless you cat it to an valid type: void is a "zero length value", or a "null value" if you prefer. Think of how it is used when you define a function that returns a void: it returns nothing at all and trying to return any value at all will throw an error, as will trying to assign the result of the function call to any variable.

Seriously, get a book. You will learn much faster and better that you are asking random questions!
Member 16116753 20-Oct-23 14:50pm    
I've got the book k5054 provided so I'll start with it, but I wanted to finish at least this topic (because I feel a bit stressed not understanding it and it can block my understanding of other stuff sorry ;<) and I will give a break. Although I think I will have again a problem same goes with random questions they are related so why is it random ;> ?

also : "It means that the pointer it returns can't be used on either side of an assignment operator unless you cat it to an valid type: void is a "zero length value", or a "null value" if you prefer." means what ? Which part ?
I've given an example, and I wanted to see if my comparison is somewhat correct. But yes while giving a question I just came up with that int * p = (int *)malloc() is similar to int *x = y in which y is int *y. So why even saying that y is a pointer same with malloc why I had to use this (int *) if not normal (int) because saying p + 1 will shift by 4 bytes because of size of(int) from int *p or with the example int *x = y, typing x + 1 will shift always by 4 bytes no matter if y is char *y or float *y it will always shift by 4 bytes. That's weird and doesn't have sense ...

And I think this will block my understanding while reading books it at least blocked my understanding while reading "Understanding and Using C Pointers". I know to read a book and I will do it I just want to finish this topic atleast.
Member 16116753 20-Oct-23 15:49pm    
Is it possible to resolve this question ? I know this is chaotic, but I feel if I won't know this I will not understand something during the learning.
Rick York 20-Oct-23 16:44pm    
A void pointer is a pointer to data of an unknown type. A double pointer is something different. That is a pointer to another pointer. In a 64-bit program a pointer is eight bytes but in a 32-bit program it is four bytes long.

Malloc doesn't exactly "have the address of a pointer." It obtains a pointer from the heap memory manager and returns that pointer to the caller. There are (at least) two basic types of memory in a program - the heap and the stack. The stack grows and shrinks automatically as functions are called and return. Non-static variables that are local to a function live on the stack. When a function is called the stack grows to accommodate those local variables along with the address to return back to. When the function returns the stack shrinks back to where it was and program execution continues at the return address that was just popped off the stack. The heap is a different piece of memory that is used when memory is allocated by calls to malloc and calloc.
Take a look at the following code which is an example of using pointers to access a function, an array of characters, and an array of integers. This uses data that is set at compile time, and other data introduced into a block of memory allocated by malloc.
C++
#include <stdio.h>
#include <memory.h>
#include <malloc.h>


// A normal function with an int parameter 
// and void return type 
void fun(int a) 
{ 
    printf("Value of a is %d\n", a); 
} 
  
int main() 
{ 
    char text[] = "Hello, World!"; // an array of characters
    char* cp = text;               // a pointer to characters
    for (; *cp != '\0'; cp++)      // iterate through the character array
    {
        printf("%c", *cp);
    }
    printf("\n\n");

    int numbers[] = { 1, 2, 3, 4, 5, -1 }; // an array of integers
    int* ip = numbers;                     // a pointer to integers
    for (; *ip != -1; ip++)                // iterate through the integer array
    {
        printf("%d, ", *ip);
    }
    printf("\n\n");

    // a function pointer 
    void (*fun_ptr)(int) = fun; 
    // Invoking fun() using fun_ptr 
    fun_ptr(10);
    printf("\n\n");

    //
    // now let's play with malloc
    //
    // note that we capture the address in a void*
    // because we don't care about the content at the moment
    //
    void* vp = malloc(100); // just grab a load of memory

    // calculate the number of bytes in the text string
    int numbytes = (sizeof(text) / sizeof(text[0])) * sizeof(char); // actual length
    // and copy them into our malloc'ed memory. 
    memcpy(vp, text, numbytes); // copy the text into it

    // we can now treat that as a character array
    // by using the correct pointer type
    cp = (char*)vp;           // capture the pointer and cast it to a character pointer
    for (; *cp != '\0'; cp++) // iterate through the character array, as beore
    {
        printf("%c", *cp);
    }
    printf("\n\n");

    // 
    // now do the same with the integers
    //
    numbytes = (sizeof(numbers) / sizeof(numbers[0])) * sizeof(int); // actual length
    memcpy(vp, numbers, numbytes); // copy the numbers into it
    ip = (int*)vp;          // capture the pointer and cast it to an integer pointer
    for (; *ip != -1; ip++) // iterate through the integer array
    {
        printf("%d, ", *ip);
    }
    printf("\n\n");

    //
    // finally let's make it an array of function pointers
    //
    printf("vp = %p\n", vp);
    (void(*)(int))vp = fun;  // set the function address
    ((void(*)(int))vp)(23);  // and execute it.

    // point to the next pointer location
    (char*)vp += sizeof(void(*)(int));
    printf("vp = %p\n", vp);
    (void(*)(int))vp = fun;  // as above
    ((void(*)(int))vp)(45);  // and execute it.

    return 0; 
}

The final two print statements show that the two dynamic function pointers are at different addresses.
 
Share this answer
 
v4
Comments
Member 16116753 21-Oct-23 6:50am    
Very thank you very much. PS.The code didn't work and the last two code "(void(*)(int))vp" are completelly not understandable for me ;D
I've read a bit of that book you've mentioned and some of the stuff has been resolved for me.

I am now experimenting this code and understand how it works :


#include <stdio.h>

int main()
{
    int *x;
    char y = 'd';
    
    x = &y;
    
    printf("%d\n", *x);
    printf("%c\n", *x);
    
    int z, g;
    z = y;
    g = *x;
    
    printf("%d\n", z);
    printf("%c\n", z);
    printf("%d\n", g);
    printf("%c\n", g);

    return 0;
}


Which gives me result of *x being a random decimal number and z being a normal decimal number.
So far I've deduced that %d from *x gives me the 4 byte value from where it points. So whenever I use *x like you did in "if" statement then I will get a decimal number? Like the variable "g" will get a integer from *x. It was just interesting because the z gave me an integer equal to 100, so I thought that it transfered the letter into an integer. And with pointer it did not transfer the letter into an integer. Which is very interesting because why then the pointer doesn't transfer the letter into an int.

PS.2

Although my teory is broken because :

#include <stdio.h>

int main()
{
int *x;
int l = 33;
x = &l;

printf("%d\n", *x);
printf("%c\n", *x);

return 0;
}

It actually shows an letter. So my theory that or reads only the 1st byte is not working ... Hmmmmm I wonder how it works.

Still very very thank you. And sorry for the trouble, because now I feel bad for what I did ;>
Richard MacCutchan 21-Oct-23 7:28am    
"the last two code "(void(*)(int))vp"
That is just a cast, telling the compiler to treat vp as something else, e.g.:
int ip = (int*)vp; // tells the compiler to treat vp as if it is an int* - just for this line
(void(*)(int))vp = fun; // tells the compiler to take the address in vp and treat it as if it points to a function, that takes an int parameter, and does not return anything.

But for now, I suggest you stick to pointers to basic types. Function pointers, while useful, are not something you are likely to need very often.
Member 16116753 21-Oct-23 7:33am    
Hmmm I still don't quite get it because vp is a variable and it is treated as pointer to the function but I will for now listen your suggestion ;>

So yea now I am working on with the think I showed in the comment. Using the book as well but it didn't answear my question so I am experimenting. But the PS.2 info I added just now destroyed my theory ;> maybe the 33 number is only written in 1 byte at the beggining the the rest are ignored maybe hmmm 33 in bytes hmm
Richard MacCutchan 21-Oct-23 7:44am    
Yes, vp is a variable, and is used as a pointer. So it can point to anything you like. In reality it will only ever point to a single byte of memory. It is the designation used by the compiler that tells it how to process whatever data is stored at the location(s) pointed to. So if you say it is a char* then the compiler will generate the instructions necessary to address a single character each time it is used. If you say it is an int* then the compiler will generate the instructions necessary to address 4 or 8* bytes as a single integer value. Similarly if you tell the compiler to use it a a function pointer it will correctly address the number of bytes necessary to hold the address of a function.

*depending on whether you are building 32-bit or 64-bit code.
Richard MacCutchan 21-Oct-23 7:38am    
    int *x;
    char y = 'd';
    
    x = &y;
    
    printf("%d\n", *x);

In the above code you have x as a pointer to an int type. You then set it to the address of y which is a char type. So when you try to print what x points to, it tries to print the integer value of 'd', which is 100. Although, because x picks an integer from that location, it will likely include some random values from the next byte locations.

if you change the code to:
    int *x;
    char y[] = "d\0\0\0\0\0\0\0";
    
    x = y;
    
    printf("%d\n", *x);

you should see the correct value.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900