I've been learning structs and I've come to the pointers to structs, where I'm currently struggling with this.
I've got this piece of code:
struct point {
int x;
int y;
} *ptr;
ptr->x = 8;
ptr->y = 8;
Running this gives a segmentation error. What I want to do is assign the value of 8 to x /y, to which, as far as I understand it, ptr is pointing to.
Your ptr is a pointer to struct point.
However, there is no struct point it is pointing to.
struct point {
int x;
int y;
} *ptr;
struct point pt; // add this...
ptr = &pt; // ...and this.
ptr->x = 8;
ptr->y = 8;
You have created a pointer called ptr but not initialized it. When you dereference it with ptr-> (or *ptr), you invoke undefined behavior which in your case is crashing the program (but could do anything).
This would be better:
struct point {
int x;
int y;
};
struct point sp = {0,0};
struct point *ptr = &sp;
sp.x = 8;
ptr->y = 8;
The problem is that the pointer ptr does not point to any valid memory buffer, assign it to a allocated or automatic storage instead:
// way 1
struct point p;
ptr = &p;
ptr->x = 8;
ptr->y = 8;
// way 2
ptr = malloc(sizeof *ptr);
ptr->x = 8;
ptr->y = 8;
// when you are done remember to release the allocated memory
free(ptr);
Let me explain you the simple way.
1.
Variables hold the data(values to want them to hold) and pointers hold only the memory address of the variables(which are just a section of memory). Pointers are used to just hold the address of the variables so they cannot hold any user data. We can although create a pointer to a variable and manipulate that variable using the specific pointer. We first need to create the variable, then we create a pointer which references that variable, then we do anything with the pointer and the variable will be manipulated.
struct point
{
int x;
int y;
};
struct point var1; //declare a variable
struct point *ptr=&var1;// declare a pointer to that variable
ptr->x = 8; // manipulate the variable
ptr->y = 8;
Or
2.
If you insist on using pointers only, then you need to allocate memory dynamically and then assign the base address of the allocated memory to the pointer.
struct point
{
int x;
int y;
} *ptr;
ptr=(struct point*)malloc(sizeof(struct point)); // this will allocate memory required to hold your structure
ptr->x = 8; //manipulate the memory content pointed by your pointer.
ptr->y = 8;
You need to assign a valid memory location to ptr, which is a pointer to struct point. You could either use malloc, or declare a variable with struct point and assign its address to ptr (like the above answers).
Btw, if ptr has file scope, then it is initialized with zero, i.e., the NULL pointer; otherwise, evaluating ptr is undefined behavior (you could get any value). In both cases, trying to dereference ptr is undefined behavior and thus you could get the segfault (in some implementation you might modified some memory location unintendedly).
Related
Has this code undefined behaviour which means for s is mandatory to allocate memory or is ok this way ?
PS: what is the difference between
struct X* x = (struct X*)malloc(sizeof(struct X));
and
struct X* x = (struct X*)malloc(sizeof(x));
and
struct X* x = (struct X*)malloc(sizeof *x);
Thank you.
#include <stdio.h>
#include <stdlib.h>
struct X
{
int x;
char* s;
};
int main()
{
struct X* x = (struct X*)malloc(sizeof(struct X));
x->x = 10;
// x->s = (char*)malloc(10);
// memcpy...
x->s = "something";
printf("is ok?");
return 0;
}
Rather than throw my own interpretation at you i felt it would be more helpful to share a link that might clarify what you are aiming to achieve:
https://www.geeksforgeeks.org/new-vs-malloc-and-free-vs-delete-in-c/
When you create a pointer i see that you have added the pointer to your char* variable / struct, but when calling them the use of the ampersand & is used as a reference to the address in the memory.
But not applied quite right using the int variable when declaring it no '*' and then referencing the location using '&'.
This is fine. Since s is part of the struct, allocating memory for the struct allocates memory for s. I would strongly suggest changing the type of s to be a const pointer, since it points to a literal which, because it's a type of constant, cannot be modified.
You cannot do s[0]='n'; after this. You did not allocate any space to hold any string other than the unmodifiable literal "something".
My understanding is that the -> operator is shorthand for dereferencing a pointer to a struct, and accessing the value of one struct member.
struct point {
int x;
int y;
};
struct point my_point = { 3, 7 };
struct point *p = &my_point; /* p is a pointer to my_point */
(*p).x = 8; /* set the first member of the struct */
p->x = 8; /* equivalent method to set the first member of the struct */
So the last 2 lines of the example above are equivalent. But I've encountered some code similar to this:
*p->x = 8
Using both the asterisk and arrow together. What does this do? Would this try to "double dereference" the pointer and assign to memory address 8, or something else? Maybe undefined behavior, or just a compiler error?
*p->x is equivalent to *(p->x) - you are dereferencing the result of p->x, which implies the x member itself has pointer type. Given a line like
*p->x = 8;
that implies x has type int *:
struct foo {
...
int *x;
...
};
Note that x must be assigned a valid pointer value before you can assign to *x. You can allocate memory dynamically:
struct foo *p = malloc( sizeof *p ); // dynamically allocate space for 1 instance of struct foo
if ( !p )
// handle allocation failure and exit here.
p->x = malloc( sizeof *p->x ); // dynamically allocate space for 1 int.
if ( !p->x )
// handle allocation failure and exit here.
Or you can set x to point to an existing int object:
int a;
...
p->x = &a;
*p->x = 8;
For a structure
struct tagp
{
int *x=someaddress;
}p0;
struct tagp *p=&p0;
*p->x accesses the address stored in the pointer x inside the structure. It is same as *((*p).x) and *(p0.x) which accesses the memory at Someaddress.
Check this link
typedef struct {
struct {
double i1, i2;
} EXP;
struct {
double i1, i2;
} SIN;
struct {
double i1, i2;
} PULSE;
struct {
double *i1, *i2;
} PWL;
} TRANS;
struct term {
TRANS trans;
struct term *nxt;
};
int main() {
struct term *look;
}
I have the above structs and the pointer look to the struct term. Could someone tell me how to dereference pointer i1 inside struct PWL?
I've tried this:
*(look->trans.PWL.i1)
but it produces segmentation fault.
Thanks in advance!
The segmentation fault is because you allocated a pointer, but did not create memory for the pointer to point at. Once you do that, then *(look->trans.PWL.i1) is indeed how to access that field in the inner struct.
You need to allocate memory for the struct, and all references within.
struct term *look = malloc(sizeof(struct term));
look->trans.PWL.i1 = malloc(sizeof(double));
look->trans.PWL.i2 = malloc(sizeof(double));
And naturally you need to reverse the process with calls to free when you are done.
free(look->trans.PWL.i2);
free(look->trans.PWL.i1);
free(look);
Or, perhaps i1 and i2 are meant to point to values that are allocated elsewhere then it would look like this:
struct term *look = malloc(sizeof(struct term));
look->trans.PWL.i1 = &look->trans.EXP.i1;
look->trans.PWL.i2 = &look->trans.EXP.i2;
And to deallocate you just free look. Remember to pair each successful call to malloc with a call to free.
Specific to PWL.i1
int main() {
struct term *look; // set up your variable
look = malloc(sizeof(struct term)); // give it some memory
look->trans.PWL.i1 = malloc(sizeof(double)); //give some memory to your double pointer
*(look->trans.PWL.i1) = 5.0; // assign it a value
printf("%lf\n", *(look->trans.PWL.i1));
return 0;
}
So since look is a pointer to a term structure, that means when you access it's elements you need to deference it then access the members (->) once you have that you just access the other members via the . operator:
look->trans.PWL.i1
In this case PWL's i1 member is a pointer so you have to deference the whole thing to assign a value. (before doing so, again you need to allocate some memory there)
And free everything when you're done of course.
struct counter{
long long counter;
}
struct instruction{
struct counter *counter
int repetitions;
void (*work_fn)(long long *);
};
int ncounter; //number of counters
struct counter *counter; //counter array
int nthreads; //number of threads
int *ninstructions; //number of instructions
struct instruction **instructions;
How does this actually works ? I am having trouble with ** pointers
A ** is just a pointer to a pointer. So where an instruction* contains the address of an instruction struct, an instruction** contains the address of an instruction* that contains the address of an instruction object.
To access the instruction pointed to by the pointer pointed to by an instruction**, you just use two asterisks instead of one, like (**p).repetitions or something similar.
You can visualize it like this:
instruction* ----> instruction
instruction** ----> instruction* ----> instruction
Remember, however, that simply declaring struct instruction** instructions; doesn't actually create an instruction struct. It just creates a pointer that holds a garbage value. You'll have to initialize it:
struct instruction inst;
// set members of inst...
*instructions = &inst;
...
(*instructions)->repetitions++; // or whatever
However, it looks like you're using an instruction** to point to an array of instruction*s. To initialize the array, you need a for loop:
instructions = malloc(sizeof(struct instruction*) * num_of_arrays);
for (i = 0; i < num_of_arrays; ++i)
instructions[i] = malloc(sizeof(struct instruction) * size_of_each_subarray);
And then you can access an element like instructions[i]->datamember.
struct instruction **instructions; // How does this actually works ? I am having trouble with ** pointers
I'm not sure what the real issue is, but I'll try to answer the question.
Double pointer is a pointer to pointer. It can be sued as array of pointers for example (if you allocate memory accordingly). For example:
instructions = malloc(5*sizeof(struct instruction*));
for (int i = 0; i < 5; i++)
instructions[i] = malloc(sizeof(struct instruction));
And you got yourself nice array of 5 pointers to struct instruction. Use it like this:
instructions[0]->repetitions = 0;
instructions is a pointer to a pointer to struct instruction.
This means that *instructions will give you a pointer to a struct instruction. This kind of construct is often used to create a dynamic array of pointers to some compound type.
I have a structure:
struct mystruct
{
int* pointer;
};
structure mystruct* struct_inst;
Now I want to change the value pointed to by struct_inst->pointer. How can I do that?
EDIT
I didn't write it, but pointer already points to an area of memory allocated with malloc.
As with any pointer. To change the address it points to:
struct_inst->pointer = &var;
To change the value at the address to which it points:
*(struct_inst->pointer) = var;
You are creating a pointer of type mystruct, I think perhaps you didn't want a pointer:
int x;
struct mystruct mystruct_inst;
mystruct_inst.pointer = &x;
*mystruct_inst.pointer = 33;
Of if you need a mystruct pointer on the heap instead:
int x;
struct mystruct *mystruct_inst = malloc(sizeof(struct mystruct));
mystruct_inst->pointer = malloc(sizeof(int));
*(mystruct_inst->pointer) = 33;
/*Sometime later*/
free(mystruct_inst->pointer);
free(mystruct_inst);