Edit: (1) Title (- previous title: How can I assign the address of a pointer to an already-existing variable? -- resolve at bottom of message); (2) 'In short'; (3) spelling / punctuation.
In short: I am trying create and then locate a struct on the heap (I want to save memory on the stack), and passing arguments into various functions to populate the struct. In previous projects I created a pointer to struct, allocated this on the heap using malloc, and finally passing the pointer as argument to functions - this worked perfectly. My question: can the same be done without the use of a pointer?
I am trying to store a struct in dynamic memory. I succeeded in a previous mini-project, but I used pointer-to-struct, and passed this pointer to all my functions. Now I am burning to know if I could simply omit passing the pointer and pass the variable struct itself into the function.
My current example
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
typedef struct s_text t_text;
typedef struct s_text
{
int letters;
// some more stuff
} t_text;
int main(void)
{
t_text text;
t_text *tp;
tp = malloc(sizeof(t_text));
//&text = tp; <-- this here I tried, but error (value required as left operand of assignment)
return (0);
}
In the above code I allocate memory on the heap for the tp. This is the memory I'd like to use. Now, on the stack, memory was reserved for (t_text) text. I would like to discard this and only use the heap.
t_text &text = malloc(sizeof(t_text));
<-- this may work in C , i don't know, but in C definitely not.
In another post's discussion on NULL pointers, someone claimed in C that the address of a variable could point to NULL with the following code
int &x = *(int*)0;
but this definitely is not appreciated by my compiler. In fact, I tried several things with the address of a variable, but each time I try to set eg &text = (some address)
this error pops up:
error: lvalue required as left operand of assignment.
(link to the post I refered to: ttps://stackoverflow.com/questions/57483/what-are-the-differences-between-a-pointer-variable-and-a-reference-variable/57492#57492 )
Below what I tried earlier (and works perfectly):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
typedef struct s_text t_text;
void fn_prompt_user(t_text *tp);
void fn_calc_letters(t_text *tp);
typedef struct s_text
{
int letters;
// some more stuff
} t_text;
int main(void)
{
t_text *tp;
tp = malloc(sizeof(t_text));
fn_prompt_user(tp);
fn_calc_letters(tp);
return (0);
}
To conclude this post with my question: Is there a way I can pass a struct variable as an argument to a function, or should I just accept passing pointer-to-struct is the one and only way to go?
Thanks!
-- answer to previous title's question (How can I assign the address of a pointer to an already-existing variable?): Not possible.
Error: error: lvalue required as left operand of assignment.
When declaring a variable, it is placed in memory. This memory location can not be changed, and so if int a = 3;
a is an lvalue (location value) which can be changed (to eg. 4), but &a is unchangeable, therefor an rvalue (so is 3). So &a = ptr_a;
will never work. Thanks for the clarification.
CodePudding user response:
You can pass a struct to a function, like ....
int myfunc(t_text mytext) {....}
then ...
t_text thistext;
...
myfunc(thistext);
and this puts the entire struct onto the stack for the subroutine to use. but the C language has no 'ref' feature like C .
You can ...
tp = (t_text *)malloc(sizeof(t_text));
myfunc(*tp);
==
Your second example, passing pointers to objects, is a very conventional means of using structs in C. It has the advantage of not needlessly copying structs to the stack, merely pointers. It has the disadvantage of allowing functions to modify the objects that are pointed to. The latter problem can be remedied by declaring that the argument points to a const struct. Like:
void fn_promt_user(const t_text *tp) {...}
CodePudding user response:
should I just accept passing pointer-to-struct is the one and only way to go?
Basically, yes.
C does not have "pass by reference" built into the language. If you want to have a function populate or otherwise modify a struct for you (or any other object for that matter), passing a pointer is the normal and idiomatic way of doing that. There is no real alternative, short of ugly macro hacks and stuff like that.