2013-03-12 8 views
2

친애 유래 매니아, 모든중첩 된 구조의 멤버 변수의 주소를 찾기

먼저 I에 유래에서 초보자입니다, 그래서 내가 커밋 실수에 대해 미리 사과드립니다.

이것은 일종의 C 퍼즐입니다. 또는 atleast 나는 그것에 의해 당혹 게했다. 코드는 아래와 같습니다.

struct outer_str 
{ 
    struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    outer_var.nest_var2.mem2 = 111; 
    printf("\n\nThe value of mem2 is %d\n\n",outer_var.nest_var2.mem2); 

    // Statement to assign mem1 of nest_str1 with a value say 333; 
    // Statement to print the value of mem1 of nest_str1; 

    return 0; 
} 

코멘트는 제안으로

는 멤버 변수 중첩 된 구조 nest_str1MEM1에게 액세스 할 수 있습니다. 또한 중첩 구조체 nest_str1에 대해 선언 된 구조체 변수가 없습니다.

희망에 반하는 희망 나는 다음 코드를 시도해 보았다. C++을 모방했다. 내가 GCC 4.6.3를 사용하여 프로그램을 컴파일

outer_var.nest_str1.mem1=333; 

은, 다음 오류가 다음

"struct outer_str has no member named 'nest_str1' ". 

를 줬습니다 나는 구조가 nest_var2의 주소에서 nest_str1의 주소를 찾는 것에 대해 생각 중첩 구조의 변수 nest_str2. 다음 코드를 시도했습니다.

int main() 
{ 
int offset; 
struct nest_str1 * addr; 
offset=sizeof(int); // There is only one integer mem1 in nest_str1 
addr=(struct nest_str1 *)((int *) & (outer_var.nest_var2) - offset); 
addr->mem1=333; 
printf("\n\nThe value of mem1 is %d\n\n",addr->mem1); 
return 0; 
} 

프로그램이 컴파일되었습니다. 그러나 결과는 내가 예상했던 것이 아니었다. 런타임 오류가 발생했습니다.

Segmentation fault (core dumped) 

이제 접근 방식이 올바른지 여부도 알지 못합니다. 그래서 나는 몇 가지 제안을 원합니다. 나는 또한 내가 분명히 간단한 해결책을 간과했을지도 모른다고 걱정한다.

아래 코드에 mem1에 액세스 할 수 있는지 여부를 알고 싶습니다.

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    }; 

}outer_var; 

귀하의 시간과 인내에 대해 미리 감사드립니다. 당신이 mem1에 액세스 할 수 있습니다 outer_var의 어떤 멤버가 없습니다

+1

구문은 위의 몇 가지 컴파일러에 의해 허용되기 때문에 어떤 사람들은 이것에 대해주의 할 필요가있다.. 그들은'nest_str1'을 구조체의 익명 (또는 이름이없는) 멤버로 간주하고 : outer_var.mem1 = 7;과 같이 _its_ 멤버에 "직접"액세스를 허용합니다. portable **! (이것은 참조 용으로 추가 된 것입니다. 일부 사람들은 그것으로 도망 갈 수 있고 다른 사람들은 그렇게 할 수 없기 때문입니다 - 그리고 여기에 많은 독자가 있습니다 ...) –

+0

@SteveValliere, 구조가 익명 인 경우 그럴 것입니다. (struct {int mem1;};') AFAIK – Nim

+0

@ _ 구조체의 존재 여부 _tag_는 _instance_ 여부에 영향을 미치지 않습니다. 구조체의 이름은 익명이거나 그렇지 않습니다. 태그없이 구조체의 인스턴스에 이름을 지정할 수 있습니다. 익명이므로 구조체 정의를 다른 곳에서 재사용 할 수 없습니다. 이것은 분명하지 않습니다. 죄송합니다. 그것은 익명 회원이 일반적으로 피할 수 있어야한다고 언급 할 가치가 있다고 생각한 이유입니다. 혼란스럽고 이식성이 없습니다. –

답변

2

(당신이 하나를 선언 한 적이 없다, 당신은 단지 nest_str1라는 유형을 정의.)

변경이에 :

struct outer_str 
{ 

    struct nest_str1 
    { 
    int mem1; 
    } nest_var1; // now there is a member! 

}outer_var; 

이제 할 수 있습니다 :

outer_var.nest_var1.mem1 = 100; 

시도가 잘못되었습니다. 예를 들어, mem1의 저장소가 없으므로 코드가 작동하더라도 mem2 위치에 쓰게 될 가능성이 큽니다.

+0

감사합니다. 그러나 구조체 outer_str의 구조체 변수 outer_var가 생성되면 어떻게 될까요? – Deepu

+0

하지만 mem2의 주소에서 오프셋을 뺍니다. – Deepu

+1

따라서 segfault는 임의의 메모리 위치에 쓰고 있습니다. 내가 말했듯이,'mem1'을위한 * storage *가 없습니다. gcc는 기본적으로 첫 번째 구조체를 * 익명 구조체로 취급하지 않습니다. 그래서, * 타입 *으로 취급됩니다.) 이름을 지우면'mem1'은'outer_var.mem1'로'outer_var'에서 액세스 할 수 있습니다.) – Nim

0

작성한 코드는 완전합니다. 그러나 두 번째 중첩 된 구조체 "outer_var.nest_var2"에서 "offset"값을 빼는 동안 타입 변환 (int )에도 불구하고 (char) 즉 "addr = (struct nest_str1 *) ((char *) & (outer_var.nest_var2) - (숯불 *) 오프셋); "당신은 첫 번째 구조 내부의 변수를 채울 수있을 것입니다

#include<stdio.h> 
#include<stdlib.h> 

struct outer_str{ 
     struct nest_str1 
    { 
    int mem1; 
    }; 
    struct nest_str2 
    { 
    int mem2; 
    }nest_var2; 
}outer_var; 

int main() 
{ 
    int offset; 
    struct nest_str1 * addr; 
    offset=sizeof(int); // There is only one integer mem1 in nest_str1 
    addr=(struct nest_str1 *)((char *) & (outer_var.nest_var2) - (char   *)offset); 
    addr->mem1=333; 
    printf("\n\nThe value of mem1 is %d\n\n",addr->mem1); 
    return 0; 
} 
관련 문제