Hi I am trying to make a program with pointer in a struct. Compiler appears no problems but the program crashes.
Could you help me please ?
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int pos;
typedef struct _Parking Parking;
struct _Parking
{
int pos;
char name[15];
char description[80];
float price;
int slots[5];
char last_driver_id;
int reservations;
};
Parking *myaccounts;
int create_Parking()
{
strcpy(myaccounts->name,"Pro");
myaccounts->pos ++;
return pos-1;
}
int main()
{
int a;
a = create_Parking();
printf("a=%d\n",a);
printf("name=%s\n",myaccounts->name);
system("pause");
return 0;
}
Your myaccounts pointer is initialized to NULL (as a global variable) and does therefore not point to usable memory. Try the manual page for malloc for more information.
Edit: Incorporated Maciej's comment.
You never allocate any memory for "myaccounts".
Pointers in C do not point to valid memory (and will crash if you try to use them), until you specifically point them somewhere valid by using the address-of operator on an object (&) or by allocating memory for them and assigning that address into the pointer (malloc() and friends). Of course if you use the address-of operator that location can go invalid when the object goes out of scope. If you use malloc() that location can go invalid when free() is called. In either case, your pointer will become invalid again.
C is hugely reliant on pointers too, so you can count on any C code you write of any size having a bug or two of this nature until you track them down and fix them. Getting your sources past the compiler in C really doesn't mean much. If you want to write in a language where your code is liable to work first time you run it after getting it past the compiler, you want Ada.
Your pointer doesn't point to anything. You can try either one of these:
Parking myaccountsInstance;
Parking *myaccounts = &myaccountsInstance;
Or in the main function:
Start with:
myaccounts = (Parking*)malloc(sizeof(Parking));
And end with:
free(myaccounts);
Related
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.
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) {...}
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.
I decided to check what value I'll get when I print the memory content of an instance of a struct:
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int value;
} Data;
int main(){
Data *d = (Data*) malloc(sizeof(Data));
printf("%d", *d);
return 0;
}
The result I got is a random value (To me) and I tried to do all kinds of experiments but not so I could understand what is behind this value. But maybe I just do not understand the way structs are stored in memory. I'd love an explanation.
The memory returned from malloc is uninitialized. Reading it before it is set will result in seeing indeterminate values (i.e. the random values you're seeing), and in some cases can trigger undefined behavior. There's no guarantee you'll even read the same value twice from the same memory location.
The way you're printing is also incorrect. You're passing an instance of a struct to printf when the given format specifier expects an int. That also causes undefined behavior.
I'm pretty new to the C. I'm trying to create a simple program to represent a point using a structure. It looks like this:
// including standard libraries
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <assert.h>
// including user defined libraries
;
typedef struct point {
char p_name;
double *p_coords;
} point_t;
int main() {
point_t *pt;
pt->p_name = "A";
printf("%c", pt->p_name);
// returning 0 if there are no errors
return 0;
}
The problem is that, when I try to print the name of the point after I assigned the name "A" to it, the program does output nothing except for the exit code, which is (probably) a random number:
Process finished with exit code -1073741819 (0xC0000005)
The fact is that pointers is a concept that is very hard for me to understand (I used to program in python before) and therefore I'm probably missing something. I've also tried out with other variable types such as int, but the result is the same (even the exit status number is the same). Is there a way to fix this behaviour?
P.S.: Excuse my rudimental English, I'm still practising it, and thanks a lot for your time!
In your code
pt->p_name = "A";
is wrong for two primary reasons:
You never made pt point to any valid memory location. Attempt to dereference an invalid memory invokes undefined behavior.
p_name is of type char. "A" is a string literal, of type char [x], which boils down to char * for assignment, and they are not compatible types.
You need to
Make sure pt points to valid memory location. Actually, you don;t need a pointer here, at all. Define pt as a variable (not a pointer variable) of the structure type, and access the members via the . operator.
Use 'A' for assignment, as in character constant, not a string.
Pointers must be made to point somewhere. You never assign a value to the pointer pt, and attempting to dereference an uninitialized pointer value invokes undefined behavior.
You're also assigning a string to a character value. String use double quotes while single characters use single quotes
Use single quotes for a character, and a pointer must first be made to point somewhere:
point_t p;
point_t *pt = &p;
pt->p_name = 'A';
printf("%c", pt->p_name);
you have to use malloc to allocate the memory of the poin_t structure.
Something like
point_t *pt = malloc(sizeof(point_t));
pt->p_name = 'A';
printf("%c", pt->p_name);
And very importantly as others mentioned is that pt->p_name = "a" is also wrong you are allocating int a char a const char* I fixed in my example
I have this simple code which causes a segfault in initstate_r:
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
int *test[8];
struct random_data rstate;
char random_bin[256];
initstate_r(1,random_bin,256,&rstate);
test[0] = NULL;
printf("%p",test[0]);
return 0;
}
It does not produce a segfault if int *test[8] lines are removed.
It doesn't seem to cause a segfault on most linux systems, but it does on ubuntu linux subsystem for windows gcc (or maybe that is just luck)?
Is my use of initstate_r actually wrong and I just get lucky sometimes? I don't see anything wrong with it?
Thanks!
From the initstate_r manual page:
Before calling this function, the buf.state field must be initialized to NULL.
You pass a pointer to the uninitialized structure rstate. That means all members of the structure will be uninitialized and have indeterminate values. If the initstate_r attempt to access these members then it could lead to undefined behavior.
You need to initialize at least the state member of the structure to a null pointer:
rstate.state = NULL;
So, I am new to pointers to in C.
I am facing a confusion.
If I have,
int a;
Here, I dont allocate memory manually for a. It's done automatically by the compiler.
Now, if in a similar fashion, if I do,
char * a;
Do I need to allocate memory for the pointer?
Secondly, I made this code,
#include <stdio.h>
int main (void)
{
int *s=NULL;
*s=100;
printf("%d\n",*s);
return 0;
}
Why do I get a seg fault in this code? Is it because I havent allocated memory for the pointer? But as asked in the above question, I can simply declare it as well without manually allocating the memory.
PS: I am new to pointers and I am facing confusion in this. Spare me if it is a bad question. Thanks.
Edit: I read the post for malloc on SO.
http://stackoverflow.com/questions/1963780/when-should-i-use-malloc-in-c-and-when-dont-i
It doesnt really solve my doubt.
You don't need to allocate memory for the pointer itself. That's automatic, like the int in your first code snippet.
What you do need to allocate is the memory that the pointer should point to, and you need to initialize the pointer to point to that.
Since you're not allocating any space, the *s= assignment is undefined behavior. s itself (the pointer) is allocated, and initialized to NULL. You can't dereference (*s - look at what the pointer points to) a null pointer.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int *s = NULL; // s is created as a null pointer, doesn't point to any memory
s = malloc(sizeof(int)); // allocate one int's worth of memory
*s = 100; // store the int value 100 in that allocated memory
printf("%d\n",*s); // read the memory back
free(s); // release the memory
// (you can't dereference s after this without
// making it point to valid memory first)
return 0;
}
You have to allocate memory for the variable s you are declaring. Malloc is a nice way to do that. With int *s=NULL the pointer does not point to any address. And after that you trying to give a value to that address (*s=100;). If you do not want to allocate memory manualy (with malloc) you simply declare an int variable and then make s pointing to that variable.
With malloc:
#include <stdio.h> int main (void)
{
int *s=NULL;
s=(int *)malloc(sizeof(int));
*s=100;
printf("%d\n",*s);
return 0;
}
Without malloc:
#include <stdio.h>
int main (void)
{
int *s=NULL;
int var;
s=&var;
*s=100;
printf("%d\n",*s);//100
printf("%d\n",var);//also 100
return 0;
}
As pointers are also special type of variables which stores the address of other variables,As the address is also some value(number), Hence memory is also needed to store this address,so compiler automatically allocates memory(exactly 4 bytes on 32-bit machine) to a pointer variable,when you are allocating the memory using malloc() or calloc()your are actually allocating the memory to the data which is to be stored,and simply assigning the starting address of this memory to the pointer.
In your example at the line
int *s=NULL; //this line
Compiler actually allocates memory of 4 bytes (if your machine is 32-bit)
see this small snippet
int main(void)
{
int *s=NULL;
printf("%d\n",sizeof(s)); //Will output 4 if you are using is 32-bit OS or else 2 if you are using using 16 bit OS.
return 0;
}
And NULL is simply just another way of assigning Zero to a pointer.So technically your actually using 4 bytes to store zeros in that pointer. And don't be confused, assigning zero or NULL means that the pointer is not pointing to any data(as it doesn't hold a valid address,Zero is not valid address).