Tenga en cuenta cómo se ve lo anterior como si debería escribirse a_foo.field, pero eso fallaría ya que Fooes un puntero a struct. Recomiendo encarecidamente contratypedef : los punteros ed en C. Los punteros son importantes, no oculte los asteriscos. Déjalos brillar.
Apuesto a que este es el problema real. Todavía me muerde en ocasiones, especialmente si alguien ha escrito un tipo de puntero.
John Bode
2
Solo agregaría que este error aparecerá si no se ha asignado una matriz (malloc) y se accede a ella.
máximo
Sé que ha pasado aproximadamente una década o más desde que se publicó esto, pero esas dos últimas oraciones hicieron de esta mi nueva publicación favorita. "Los punteros son importantes, no ocultes tus asteriscos. Déjalos brillar".
Aiden Blishen Cuneo
20
Está intentando acceder a un miembro de una estructura, pero en algo que no es una estructura. Por ejemplo:
Gracias por hacer explícito el punto del puntero (ningún juego terrible de lenguaje). Otras respuestas lo mencionaron (por ejemplo, "deja que tus punteros brillen"), pero a las 2 a. M., Luchando en una batalla épica con BGF y Valgrind, personas como yo apreciamos que tu respuesta muestre explícitamente cómo el puntero puede ser un problema y cómo se puede corregir ese problema. .
Max von Hippel
3
He enumerado posiblemente todos los casos en los que este error puede ocurrir en el código y sus comentarios a continuación. Añádalo si encuentra más casos.
#include<stdio.h>#include<malloc.h>typedefstructAStructTypedefedStruct;structAStruct
{int member;
};
voidmain(){
/* Case 1
============================================================================
Use (->) operator to access structure member with structure pointer, instead
of dot (.) operator.
*/structAStruct *aStructObjPtr = (structAStruct *)malloc(sizeof(structAStruct));//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 ->structAStruct **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
}
Las ideas subyacentes son rectas:
Usar .con variable de estructura. (Casos 2 y 4)
Usar ->con puntero para estructurar. (Casos 1 y 3)
Si alcanza la variable de estructura o el puntero a la variable de estructura siguiendo el puntero, envuelva el puntero dentro del corchete: (*ptr).y (*ptr)->vs *ptr.y *ptr-> (Todos los casos excepto el caso 1)
Si está alcanzando siguiendo los punteros, asegúrese de haber alcanzado correctamente el puntero a la estructura o estructura, lo que desee. (Caso 5, especialmente 5.5)
Respuestas:
También sucede si está intentando acceder a una instancia cuando tiene un puntero y viceversa:
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 */
Como se señaló en un comentario, esto puede volverse insoportable si alguien va y
typedef
un puntero, es decir, incluye el*
en un typedef, así:typedef struct foo* Foo;
Porque luego obtienes un código que parece estar tratando con instancias, cuando en realidad se trata de punteros:
Tenga en cuenta cómo se ve lo anterior como si debería escribirse
a_foo.field
, pero eso fallaría ya queFoo
es un puntero a struct. Recomiendo encarecidamente contratypedef
: los punteros ed en C. Los punteros son importantes, no oculte los asteriscos. Déjalos brillar.fuente
Está intentando acceder a un miembro de una estructura, pero en algo que no es una estructura. Por ejemplo:
struct { int a; int b; } foo; int fum; fum.d = 5;
fuente
También puede ocurrir en el siguiente caso:
p.ej. si consideramos la función push de una pila:
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; }
El error está en la función push y en la línea comentada. El puntero
s
debe incluirse entre paréntesis. El código correcto:scanf("%d",&( (*s)->a[++(*s)->head]));
fuente
He enumerado posiblemente todos los casos en los que este error puede ocurrir en el código y sus comentarios a continuación. Añádalo si encuentra más casos.
#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 }
Las ideas subyacentes son rectas:
.
con variable de estructura. (Casos 2 y 4)->
con puntero para estructurar. (Casos 1 y 3)(*ptr).
y(*ptr)->
vs*ptr.
y*ptr->
(Todos los casos excepto el caso 1)fuente
Puede significar que olvidó incluir un archivo de encabezado que defina esta estructura / unión. Por ejemplo:
Archivo foo.h:
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();
archivo main.c:
. . . if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */ . . .
fuente
también puede aparecer si:
struct foo { int x, int y, int z }foo; foo.x=12
en vez de
struct foo { int x; int y; int z; }foo; foo.x=12
fuente