I need help assigning a value to an array with in a structure. Your help is greatly appreciated:
typedef struct _temp_t {
int16_t _values[4];
} TEMP_T;
void func() {
TEMP_T *temps;
int x = 5;
temps._values[0] = x;
}
I'm getting an error :
...src/rodm/ucdCom.c:512: error: request for member '_values' in something not a structure or union
Your help is greatly appreciated!
TEMP_T *temps;
temps is a pointer, so it has no members, only structs and unions have members.
After you allocated memory for temps, you could set
temps->_values[0] = x;
Or you can declare temps as a TEMP_T,
TEMP_T temps;
and leave the rest of the code as is.
TEMP_T *temps;
Drop the * from that line. Then it will be a true TEMP_T object instead of a pointer.
Alternatively, malloc some memory to temps and then use:
temps->_values[0] = x;
The OP didn't have any sign of an allocated struct TEMPT_T anywhere.
He had a pointer, but nothing for it to point to. His code then attempts an assignment with member access syntax (temps._values[0];), as opposed to pointer access syntax (temps->_values[0];).
A slightly better version of his code might look like:
typedef struct _temp_t {
int16_t _values[4];
} TEMP_T;
void func(struct TEMPT_T in) {
TEMP_T *temps = ∈
int x = 5;
temps->_values[0] = x;
}
The function's new definition implies that a struct TEMP_T must exist for it to be used, and thus the pointer access into the structure becomes legal.
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".
Let my structures be:
typedef struct{
double x;
double y;
} punt;
typedef struct{
char tip;
punt infEsq
punt supDret;
} rectangle;
typedef struct{
rectangle *llista;
int numRect;
int midaMax;
} taulaRectangle;
Contextualizing,
"Punt" represents a point.
"Rectangle", char indicates if it's a square [q] or a rectangle [r], the two points are the inferior left point (infEsq) and the superior right point (supDret) of the rectangle.
"TaulaRectangle" maps a list (or table) of structures type "rectangle", indicating how many rectangles it has [numRect], and how many it can hold [midaMax] (which if I am not wrong indicates the dimension of [llista]).
Now I want to code a function to initialize a pointer to "taulaRectangle" like this:
void initaula(taulaRectangle *t,int n) /*n is associated to midaMax*/
I will not post my intents in coding a valid initialization function because I believe they're not close to what I want to achieve although here is a similar scenario where I did try something alike:
void inipunt(punt *b){
b->x=0;
b->y=1;
return;
}
int main (void){
double b,n;
punt *a;
inipunt(a);
puts("guay");
a.x=b;
a.y=n;
printf("a.x=%lf a.y=%lf",b,n); /*I know this association is not necessary
but if I directly print a.x a.y it does
not work either, also a fail is *(a.x),*
(a.y) */
return 0;
}
The compiler (gcc -ansi -Wall) returns:
final1.c:30:2: error: request for member ‘x’ in something not a
structure or union a.x=b; ^ final1.c:31:2: error: request for
member ‘y’ in something not a structure or union a.y=n; ^
Synthesizing, I want to be able to declare a pointer to "taulaRectangle" and initialize it using "void initaula()", I typed the example above because I believe what I want to achieve in both functions is similar except in "void inipunt()" I do not have to allocate memory for a pointer in the structure, I think the problem has it's roots in how i treat the pointer to the structure in my void function.
Sorry for the long question, if anyone can help It will be gladly appreciated.
As Eugene pointed out in the comments, the pointer is not allocated.
When you do punt *a;, you're only allocating a pointer to the structure, but it doesn't point to anything yet. It's not initialized.
Keep your uninitialized variables in check, as they could have any value. You have no idea what an uninitialized pointer could be pointing to.
You have two solutions for this problem:
Allocate space for the structure in the stack, by doing punt a;. In this case a is the struct.
Allocate space for the structure in the heap, by doing punt *a = malloc(sizeof(punt)). In this case a is a pointer to the struct.
If you allocate the space in the stack, to get the pointer for a, you should do &a.
Keep in mind that to access a struct behind a pointer, you use -> instead of ..
This should work:
void inipunt(punt *p) {
p->x = 0;
p->y = 1;
}
int main() {
punt a;
inipunt(&a);
printf("%lf %lf\n", a.x, a.y);
punt *b = malloc(sizeof(punt)); // You should check if it returns NULL, in case of an error.
inipunt(b);
printf("%lf %lf\n", b->x, b->y);
return 0;
}
I am reading a book called "Teach Yourself C in 21 Days" (I have already learned Java and C# so I am moving at a much faster pace). I was reading the chapter on pointers and the -> (arrow) operator came up without explanation. I think that it is used to call members and functions (like the equivalent of the . (dot) operator, but for pointers instead of members). But I am not entirely sure.
Could I please get an explanation and a code sample?
foo->bar is equivalent to (*foo).bar, i.e. it gets the member called bar from the struct that foo points to.
Yes, that's it.
It's just the dot version when you want to access elements of a struct/class that is a pointer instead of a reference.
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = malloc(sizeof(struct foo));
var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;
That's it!
I'd just add to the answers the "why?".
. is standard member access operator that has a higher precedence than * pointer operator.
When you are trying to access a struct's internals and you wrote it as *foo.bar then the compiler would think to want a 'bar' element of 'foo' (which is an address in memory) and obviously that mere address does not have any members.
Thus you need to ask the compiler to first dereference whith (*foo) and then access the member element: (*foo).bar, which is a bit clumsy to write so the good folks have come up with a shorthand version: foo->bar which is sort of member access by pointer operator.
a->b is just short for (*a).b in every way (same for functions: a->b() is short for (*a).b()).
foo->bar is only shorthand for (*foo).bar. That's all there is to it.
Well I have to add something as well. Structure is a bit different than array because array is a pointer and structure is not. So be careful!
Lets say I write this useless piece of code:
#include <stdio.h>
typedef struct{
int km;
int kph;
int kg;
} car;
int main(void){
car audi = {12000, 230, 760};
car *ptr = &audi;
}
Here pointer ptr points to the address (!) of the structure variable audi but beside address structure also has a chunk of data (!)! The first member of the chunk of data has the same address than structure itself and you can get it's data by only dereferencing a pointer like this *ptr (no braces).
But If you want to acess any other member than the first one, you have to add a designator like .km, .kph, .kg which are nothing more than offsets to the base address of the chunk of data...
But because of the preceedence you can't write *ptr.kg as access operator . is evaluated before dereference operator * and you would get *(ptr.kg) which is not possible as pointer has no members! And compiler knows this and will therefore issue an error e.g.:
error: ‘ptr’ is a pointer; did you mean to use ‘->’?
printf("%d\n", *ptr.km);
Instead you use this (*ptr).kg and you force compiler to 1st dereference the pointer and enable acess to the chunk of data and 2nd you add an offset (designator) to choose the member.
Check this image I made:
But if you would have nested members this syntax would become unreadable and therefore -> was introduced. I think readability is the only justifiable reason for using it as this ptr->kg is much easier to write than (*ptr).kg.
Now let us write this differently so that you see the connection more clearly. (*ptr).kg ⟹ (*&audi).kg ⟹ audi.kg. Here I first used the fact that ptr is an "address of audi" i.e. &audi and fact that "reference" & and "dereference" * operators cancel eachother out.
struct Node {
int i;
int j;
};
struct Node a, *p = &a;
Here the to access the values of i and j we can use the variable a and the pointer p as follows: a.i, (*p).i and p->i are all the same.
Here . is a "Direct Selector" and -> is an "Indirect Selector".
I had to make a small change to Jack's program to get it to run. After declaring the struct pointer pvar, point it to the address of var. I found this solution on page 242 of Stephen Kochan's Programming in C.
#include <stdio.h>
int main()
{
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = &var;
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f\n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f\n", pvar->x, pvar->y);
return 0;
}
Run this in vim with the following command:
:!gcc -o var var.c && ./var
Will output:
5 - 14.30
6 - 22.40
#include<stdio.h>
int main()
{
struct foo
{
int x;
float y;
} var1;
struct foo var;
struct foo* pvar;
pvar = &var1;
/* if pvar = &var; it directly
takes values stored in var, and if give
new > values like pvar->x = 6; pvar->y = 22.4;
it modifies the values of var
object..so better to give new reference. */
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f\n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f\n", pvar->x, pvar->y);
return 0;
}
The -> operator makes the code more readable than the * operator in some situations.
Such as: (quoted from the EDK II project)
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
struct _EFI_BLOCK_IO_PROTOCOL {
///
/// The revision to which the block IO interface adheres. All future
/// revisions must be backwards compatible. If a future version is not
/// back wards compatible, it is not the same GUID.
///
UINT64 Revision;
///
/// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
///
EFI_BLOCK_IO_MEDIA *Media;
EFI_BLOCK_RESET Reset;
EFI_BLOCK_READ ReadBlocks;
EFI_BLOCK_WRITE WriteBlocks;
EFI_BLOCK_FLUSH FlushBlocks;
};
The _EFI_BLOCK_IO_PROTOCOL struct contains 4 function pointer members.
Suppose you have a variable struct _EFI_BLOCK_IO_PROTOCOL * pStruct, and you want to use the good old * operator to call it's member function pointer. You will end up with code like this:
(*pStruct).ReadBlocks(...arguments...)
But with the -> operator, you can write like this:
pStruct->ReadBlocks(...arguments...).
Which looks better?
#include<stdio.h>
struct examp{
int number;
};
struct examp a,*b=&a;`enter code here`
main()
{
a.number=5;
/* a.number,b->number,(*b).number produces same output. b->number is mostly used in linked list*/
printf("%d \n %d \n %d",a.number,b->number,(*b).number);
}
output is 5
5 5
Dot is a dereference operator and used to connect the structure variable for a particular record of structure.
Eg :
struct student
{
int s.no;
Char name [];
int age;
} s1,s2;
main()
{
s1.name;
s2.name;
}
In such way we can use a dot operator to access the structure variable
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.
Is there an easy explanation for what this error means?
request for member '*******' in something not a structure or union
I've encountered it several times in the time that I've been learning C, but I haven't got a clue as to what it means.
It also happens if you're trying to access an instance when you have a pointer, and vice versa:
struct foo
{
int x, y, z;
};
struct foo a, *b = &a;
b.x = 12; /* This will generate the error, should be b->x or (*b).x */
As pointed out in a comment, this can be made excruciating if someone goes and typedefs a pointer, i.e. includes the * in a typedef, like so:
typedef struct foo* Foo;
Because then you get code that looks like it's dealing with instances, when in fact it's dealing with pointers:
Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;
Note how the above looks as if it should be written a_foo.field, but that would fail since Foo is a pointer to struct. I strongly recommend against typedef:ed pointers in C. Pointers are important, don't hide your asterisks. Let them shine.
You are trying to access a member of a structure, but in something that is not a structure. For example:
struct {
int a;
int b;
} foo;
int fum;
fum.d = 5;
It may also happen in the following case:
eg. if we consider the push function of a stack:
typedef struct stack
{
int a[20];
int head;
}stack;
void push(stack **s)
{
int data;
printf("Enter data:");
scanf("%d",&(*s->a[++*s->head])); /* this is where the error is*/
}
main()
{
stack *s;
s=(stack *)calloc(1,sizeof(stack));
s->head=-1;
push(&s);
return 0;
}
The error is in the push function and in the commented line. The pointer s has to be included within the parentheses. The correct code:
scanf("%d",&( (*s)->a[++(*s)->head]));
I have enumerated possibly all cases where this error may occur in code and its comments below. Please add to it, if you come across more cases.
#include<stdio.h>
#include<malloc.h>
typedef struct AStruct TypedefedStruct;
struct AStruct
{
int member;
};
void main()
{
/* Case 1
============================================================================
Use (->) operator to access structure member with structure pointer, instead
of dot (.) operator.
*/
struct AStruct *aStructObjPtr = (struct AStruct *)malloc(sizeof(struct AStruct));
//aStructObjPtr.member = 1; //Error: request for member ‘member’ in something not
//a structure or union.
//It should be as below.
aStructObjPtr->member = 1;
printf("%d",aStructObjPtr->member); //1
/* Case 2
============================================================================
We can use dot (.) operator with struct variable to access its members, but
not with with struct pointer. But we have to ensure we dont forget to wrap
pointer variable inside brackets.
*/
//*aStructObjPtr.member = 2; //Error, should be as below.
(*aStructObjPtr).member = 2;
printf("%d",(*aStructObjPtr).member); //2
/* Case 3
=============================================================================
Use (->) operator to access structure member with typedefed structure pointer,
instead of dot (.) operator.
*/
TypedefedStruct *typedefStructObjPtr = (TypedefedStruct *)malloc(sizeof(TypedefedStruct));
//typedefStructObjPtr.member=3; //Error, should be as below.
typedefStructObjPtr->member=3;
printf("%d",typedefStructObjPtr->member); //3
/* Case 4
============================================================================
We can use dot (.) operator with struct variable to access its members, but
not with with struct pointer. But we have to ensure we dont forget to wrap
pointer variable inside brackets.
*/
//*typedefStructObjPtr.member = 4; //Error, should be as below.
(*typedefStructObjPtr).member=4;
printf("%d",(*typedefStructObjPtr).member); //4
/* Case 5
============================================================================
We have to be extra carefull when dealing with pointer to pointers to
ensure that we follow all above rules.
We need to be double carefull while putting brackets around pointers.
*/
//5.1. Access via struct_ptrptr and ->
struct AStruct **aStructObjPtrPtr = &aStructObjPtr;
//*aStructObjPtrPtr->member = 5; //Error, should be as below.
(*aStructObjPtrPtr)->member = 5;
printf("%d",(*aStructObjPtrPtr)->member); //5
//5.2. Access via struct_ptrptr and .
//**aStructObjPtrPtr.member = 6; //Error, should be as below.
(**aStructObjPtrPtr).member = 6;
printf("%d",(**aStructObjPtrPtr).member); //6
//5.3. Access via typedefed_strct_ptrptr and ->
TypedefedStruct **typedefStructObjPtrPtr = &typedefStructObjPtr;
//*typedefStructObjPtrPtr->member = 7; //Error, should be as below.
(*typedefStructObjPtrPtr)->member = 7;
printf("%d",(*typedefStructObjPtrPtr)->member); //7
//5.4. Access via typedefed_strct_ptrptr and .
//**typedefStructObjPtrPtr->member = 8; //Error, should be as below.
(**typedefStructObjPtrPtr).member = 8;
printf("%d",(**typedefStructObjPtrPtr).member); //8
//5.5. All cases 5.1 to 5.4 will fail if you include incorrect number of *
// Below are examples of such usage of incorrect number *, correspnding
// to int values assigned to them
//(aStructObjPtrPtr)->member = 5; //Error
//(*aStructObjPtrPtr).member = 6; //Error
//(typedefStructObjPtrPtr)->member = 7; //Error
//(*typedefStructObjPtrPtr).member = 8; //Error
}
The underlying ideas are straight:
Use . with structure variable. (Cases 2 and 4)
Use -> with pointer to structure. (Cases 1 and 3)
If you reach structure variable or pointer to structure variable by following pointer, then wrap the pointer inside bracket: (*ptr). and (*ptr)-> vs *ptr. and *ptr-> (All cases except case 1)
If you are reaching by following pointers, ensure you have correctly reached pointer to struct or struct whichever is desired. (Case 5, especially 5.5)
It may means that you forgot include a header file that define this struct/union.
For example:
foo.h file:
typedef union
{
struct
{
uint8_t FIFO_BYTES_AVAILABLE : 4;
uint8_t STATE : 3;
uint8_t CHIP_RDY : 1;
};
uint8_t status;
} RF_CHIP_STATUS_t;
RF_CHIP_STATUS_t getStatus();
main.c file:
.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */
.
.
.
can also appear if:
struct foo { int x, int y, int z }foo;
foo.x=12
instead of
struct foo { int x; int y; int z; }foo;
foo.x=12
I saw this when I was trying to access the members.
My struct was this:
struct test {
int a;
int b;
};
struct test testvar;
Normally we access structure members as
testvar.a;
testvar.b;
I mistook testvar to be a pointer and did this.
testvar->a;
That's when I saw this error.
request for member ‘a’ in something not a structure or union
My ridiculous experience is that I incorrectly put '.' instead of ','.
printf("%c". ch);