“구조 또는 조합이 아닌 구성원 '*******'에 대한 요청”은 무엇을 의미합니까?


81

이 오류가 의미하는 바에 대한 쉬운 설명이 있습니까?

request for member '*******' in something not a structure or union

나는 C를 배우면서 여러 번 만났지만 그것이 의미하는 바에 대한 단서가 없습니다.


더 나은 대답은 정상에 받아 들여 져야합니다.
T.Woody 2014 년

답변:


115

포인터가있을 때 인스턴스에 액세스하려는 경우에도 발생하며 그 반대의 경우도 마찬가지입니다.

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 */

주석에서 지적했듯이 누군가가 typedef포인터를 sa 로 가면 , 즉 *typedef에를 포함하면 다음과 같이 극심하게 만들 수 있습니다 .

typedef struct foo* Foo;

그러면 실제로 포인터를 처리 할 때 인스턴스를 처리 하는 것처럼 보이는 코드가 생성되기 때문입니다.

Foo a_foo = get_a_brand_new_foo();
a_foo->field = FANTASTIC_VALUE;

위의 내용이 작성되어야하는 것처럼 보이지만 struct에 대한 포인터 a_foo.field이므로 실패 Foo합니다. 나는 C의 : ed 포인터에 대해 강력히 추천합니다 typedef. 포인터는 중요합니다. 별표를 숨기지 마십시오. 빛나게하십시오.


8
이것이 실제 문제라고 장담합니다. 특히 누군가가 포인터 유형을 typedef 한 경우에는 여전히 나를 물었습니다 .
John Bode

2
배열이 할당되지 않았고 (malloc) 액세스 된 경우이 오류가 나타날 것이라고 덧붙였습니다.
최대

이 글이 게시 된 지 약 10 년이 지났지 만 마지막 두 문장이이 글을 제가 좋아하는 새로운 글로 만들었습니다. "포인터는 중요합니다. 별표를 숨기지 마십시오. 빛나게하십시오."
Aiden Blishen Cuneo

20

구조의 구성원에 액세스하려고하지만 구조가 아닌 항목에 액세스하려고합니다. 예를 들면 :

struct {
    int a;
    int b;
} foo;
int fum;
fum.d = 5;

5

다음과 같은 경우에도 발생할 수 있습니다.

예. 스택의 푸시 기능을 고려하면 :

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;
}

오류는 푸시 기능과 주석 처리 된 줄에 있습니다. 포인터 s는 괄호 안에 포함되어야합니다. 올바른 코드 :

scanf("%d",&( (*s)->a[++(*s)->head]));

2
포인터 포인트 (언어에 대한 끔찍한 플레이 없음)를 명시 적으로 만들어 주셔서 감사합니다. 다른 답변에서 언급했지만 (예 : "포인터를 빛나게하십시오"), 오전 2시 GDB 및 Valgrind와의 장대 한 전투에서 고군분투하고있는 저와 같은 사람들은 귀하의 답변이 포인터가 문제가 될 수있는 방법과 문제가 해결 될 수있는 방법을 명시 적으로 보여 준다는 점을 고맙게 생각합니다. .
Max von Hippel

3

이 오류가 코드 및 아래 주석에서 발생할 수있는 모든 경우를 열거했습니다. 더 많은 사례를 발견하면 추가하십시오.

#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
}

기본 아이디어는 다음과 같습니다.

  • .구조 변수와 함께 사용 합니다. (사례 2 및 4)
  • ->구조에 대한 포인터와 함께 사용합니다 . (사례 1 및 3)
  • 포인터를 따라 구조 변수 또는 구조 변수에 대한 포인터에 도달하면 포인터를 대괄호로 감싼다 : (*ptr).(*ptr)->vs *ptr.*ptr-> (케이스 1을 제외한 모든 경우)
  • 포인터를 따라 도달하는 경우 원하는 구조체 또는 구조체에 대한 포인터에 올바르게 도달했는지 확인하십시오. (Case 5, 특히 5.5)

1

이 struct / union을 정의하는 헤더 파일을 포함하는 것을 잊었 음을 의미 할 수 있습니다. 예를 들면 :

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();

main.c 파일 :

.
.
.
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the  #include "foo.h" */
.
.
.

0

다음과 같은 경우에도 나타날 수 있습니다.

struct foo {   int x, int y, int z }foo; 

foo.x=12

대신에

struct foo {   int x; int y; int z; }foo; 

foo.x=12

이 두 진술 사이에 차이가 없습니까?
Nick Predey

1
@AlaaM. 몇 달 후 돌아보며 세미콜론을 놓쳤습니다!
Nick Predey 2016
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.