Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I understand that this question is probably for another topic or thread but I have this little problem trying to understand memory allocation in C. I want to allocate memory from inside a function A() and use this memory from another function B(). The whole process should be controlled from main...
To help you understand on what I mean, I wrote this simple program. But after a successful compilation It gives me many memory allocation errors when run. And memory segmentation errors if I move the definition struct apoint *p outside the main(). How can I correct this to have a successful run?
Please someone with great experience in C could help me?
tried your code in windows and it crashed, dont know why.
this is because of Segment Violation
But I don't know what causes it ...
In linux also crashes ...
Unfortunately all malloc() examples I have seen so far use it inside main(). But the application I write ( a small database) Is very big to fit in main() so I have to split it in functions ... Any Ideas?
I'm a huge fan of C ... but frankly, this kind of design cries out for a C++ class (instead of a C struct with a C malloc in a C "initial()" function).
Anyway:
Code:
#include <stdio.h>
#include <stdlib.h>
/*
* Global typedefs and definitions
*/
struct apoint
{
int x ,y;
};
/*
* Function prototypes
*/
void allocate (struct apoint **point_pp);
void init2 (struct apoint *point_p);
void printpnt (struct apoint *point_p);
/*
* allocate: Allocate space for, and initialize an "apoint" structure
*/
void allocate (struct apoint **point_pp) {
*point_pp = (struct apoint *) malloc (sizeof (struct apoint));
*point_pp->x = 10;
*point_pp->y = 35;
}
/*
* init2: Assume memory is allocated - just initialize the struct
*/
void init2 (struct apoint *point_p) {
point->x = 10;
point->y = 35;
}
/*
* printpnt: Dump the value of "point"
*/
void printpnt (struct apoint *point_p) {
printf ("(x , y) = (%d , %d)\n", point_p->x , point_p->y);
}
/*
* program root
*/
int main(void) {
struct apoint *point1_p = NULL;
struct apoint point2;
allocate (&point1_p);
printpnt (point1_p);
init2 (&point2);
printpnt (&point2);
return 0;
}
I'm a huge fan of C ... but frankly, this kind of design cries out for a C++ class
But the problem in the original code just calls out for the C++ feature of pass by reference.
In C you can get the semantic equivalent of pass by reference (using uglier syntax) with the method you showed: Add an extra level of indirection.
But in this example in C, that obscures the function and there was a simpler solution.
The apoint* is conceptually the return value of the allocate function. There are many times in C where it is appropriate to implement a conceptual return value by passing a pointer in rather than passing the value out. But in simple cases like this one, a conceptual return value is best implemented as an actual return value.
you need a double pointer because its actually a pointer to a pointers
so you get the real thing not a copy of it
No! There is no reason to add the extra level of indirection for printpnt.
The extra level of indirection was needed for allocate() when a value that is effectively an output from allocate() was declared as an input.
If you have a good reason to pass a function output as an input to that function (there are often such good reasons) then the way to deal with that in C is to add a level of indirection.
But the apoint* is just an input to printpnt(). Adding an extra level of indirection there just confuses things.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Rep:
Quote:
Originally Posted by johnsfine
But the problem in the original code just calls out for the C++ feature of pass by reference.
In C you can get the semantic equivalent of pass by reference (using uglier syntax) with the method you showed: Add an extra level of indirection.
k
But in this example in C, that obscures the function and there was a simpler solution.
The apoint* is conceptually the return value of the allocate function. There are many times in C where it is appropriate to implement a conceptual return value by passing a pointer in rather than passing the value out. But in simple cases like this one, a conceptual return value is best implemented as an actual return value.
No! There is no reason to add the extra level of indirection for printpnt.
The extra level of indirection was needed for allocate() when a value that is effectively an output from allocate() was declared as an input.
If you have a good reason to pass a function output as an input to that function (there are often such good reasons) then the way to deal with that in C is to add a level of indirection.
But the apoint* is just an input to printpnt(). Adding an extra level of indirection there just confuses things.
No, not this time. I do make such mistakes (focus on the content of a post when I should have paid more attention to who posted it). But this time I did notice who posted it.
I posted a correction to your code mainly to keep the OP from being confused by your suggestion. But maybe you can also learn something here.
Hi! not confused, on the contrary ...
I prefer smeezekitty's solution.
the struct apoint* allocate() solution applies in this simple example but not in the application I write, where functions have to return multiple pointer values...
I prefer smeezekitty's solution.
the struct apoint* allocate() solution applies in this simple example but not in the application I write, where functions have to return multiple pointer values.
Notice I qualified my comments on Paulsm4's suggestion twice with statements like
Quote:
There are many times in C where it is appropriate to implement a conceptual return value by passing a pointer in rather than passing the value out.
I anticipated that the solution I suggested for this simple case could not replace Paulsm4's suggestion in more complicated cases.
I still think it is better to use straight forward code in the simple case and save the more complicated solutions for more complicated problems. But if you want to practice the complicated solution on a simple problem, that's your choice.
I hope you understand that there is an additional flaw in Smeezkitty's expansion of Paulsm4's solution. If a value is just an input, not one of multiple return values, not even a single return value, adding the extra layer of indirection just adds overhead and confusion.
Gentle suggestion - when you hear people babbling subjective nonsense about "straight forward code" and "uglier syntax" - run!
But to go back to your original question:
Quote:
I want to allocate memory from inside a function A() and use this memory from another function B(). The whole process should be controlled from main...
Unfortunately all malloc() examples I have seen so far use it inside main()
The answer to this question (all irrelevant issues of "style" aside) is simply:
Quote:
you need to use a pointer to a pointer (**p)
Q: Do you understand why?
Q: Why does passing "**p" as an argument (my reply) do the same thing as returning "*p" as a "return" value (johnsfine's suggestion)?
Q: What would happen if you wanted to allocate memory for TWO (or three, or more) structs, instead of just one?
I think the main point is to understand "pointer", "address", and "pointer to pointer".
And again, if this were C++ ... then your "struct" would be a "class", your "allocate()" would be a "constructor" ... and we probably wouldn't even be having this conversation
Anyway - I hope this discussion was useful for you.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.