2013-02-04 1 views
1

가능한 중복 할당되는 방법 :
Why isn’t sizeof for a struct equal to the sum of sizeof of each member?메모리는 구조체의 형식 정의의의에 대한 (C)

당신은 예를 들어, C에서 구조체, 만들 때 :

typedef struct student 
{ 

int roll_no; 
char* name; 
int* pointer; 


}student; 

을 나는 roll_no와 name이 연속적으로 메모리에 저장되지 않는다는 것을 알아 차렸다. 이게 어떻게 작동합니까? 목표가이 데이터를 캡슐화하는 것이라면 연속적으로 저장하면 더 좋지 않겠습니까? 컴파일러는 이러한 데이터 조각이 함께 있다는 것을 어떻게 알 수 있습니까?

+0

[구조 패딩] (http://en.wikipedia.org/wiki/Data_structure_alignment#Data_structure_padding)을 읽으십시오. 'typedef'는'type'을위한 별칭만을 생성합니다, 그것은 새로운 데이터 타입을 정의하지 않습니다. –

+0

[이 구조체 정렬에 대한 답변] (http://stackoverflow.com/a/119128/1887090)에는 좋은 설명과 예제가 있습니다. – Walfie

답변

1

컴파일러는 아키텍처 요구 사항과 일치하도록 구조체의 각 요소의 시작을 맞 춥니 다. 이것은 일반적으로 단어 경계선에 정렬이 있음을 의미하지만 엄격하고 빠른 규칙은 없습니다.

typedef는 정렬에 아무런 영향을 미치지 않습니다. typedef는 단순히 구조체처럼 어떤 객체에 대한 "속기 참조"를 만듭니다. typedef를 동의어로 생각할 수 있습니다.

0

연속적으로 저장됩니다. char * 이름 안에 포함 된 주소는 다른 곳에서 온 것입니다. 메모리에 연속적으로 저장하려면 포인터 대신 배열을 사용하십시오.

이것은 메모리에 저장되는 방법입니다. 예를 들어, struct의 주소는 1000 (십진수)에서 시작합니다.

1000 roll_no 
1004 name 
1008 pointer 

이름과 포인터는 malloc에 ​​의해 할당 된 값 (주소)을 보유합니다. 모두가 아키텍처의 레지스터 크기 (일반적으로 32 또는 64 비트)의 크기 즉, (심지어 포인터이다)의 int 때문에

s->name = malloc(100); 
s->pointer = malloc(4); 

이 경우에는 구조 패딩이 없다.

1

name은 실제로 struct과 함께 저장되지 않습니다. 포인터 만 저장되어 있습니다. 데이터는 일반적으로 struct 외부 영역에서 동적으로 할당됩니다.

struct과 함께 이름을 저장하려면 배열로 지정해야합니다. 이 방법의 단점은 문자열이 고정 길이 여야합니다 (즉, 모두 struct이 최대 길이 name에 충분한 메모리 양을 할당하거나 끝에 name[] 배열을 선언하여 유연한 배열 요소를 사용해야 함) struct의 단점은 (1) 할당이 훨씬 복잡해지고, (2) 해당 배열을 만들 수 없으며 (3) 구조에 하나의 유연한 배열 만 가질 수 있다는 것입니다.

0

데이터는 연속적으로 저장되지만 단어 경계에 대한 최적화 및 정렬로 인해 데이터가 저장 될 수 있습니다. 실행중인 프로세서와 컴파일러 옵션에 따라 달라집니다 (포장)

컴파일러는 구조체의 오프셋을 계산하므로 구조체의 요소를 가져 오기 위해 메모리를 조회 할 수 있습니다.

0

사실

struct student 
{ 
    int roll_no; 
    char* name; 
    int* pointer; 
} 

C 정확하게 당신이 원하는 않는 구조체에서 ("구조 패딩"그러나 이것은 또 다른 이야기입니다 외에). 인텔 프로세서에 gcc를 가정하면, 구조체는 포인터

  • 4 바이트 포인터 int *의에 의해, 이름
  • 4 바이트 포인터 char *의 다음, int

    • 4 바이트로 만든 다음에

    이름 회원은 ch ar (s), 일반적으로 메모리의 어딘가에있는 문자 스트링을 가리키는 포인터. 여기

    char *string = "John Doe"; 
    int value = 255; 
    struct student me; 
    
    me.roll_no = 15; 
    me.name = string; 
    me.pointer = &value; 
    

    예를

    를 들어 문자열 메모리 어딘가에 - 당신이 지금까지 구조 이전에 선언 발견한다. 그래서 우리는 문자열을 에 대한 주소와 20000000 당신이 구조가 15에 대한 0F000000입니다 참조

    0x12345678 : John Doe\0 
    ... 
    0x20000000 : FF000000 // 255 
    ... 
    0x22222222 : 0F00000
    

    , 12345678이 메모리 위치 0x12345678이며, 0x20000000에 있으며 구조가 0x22222222에 있습니다 말 주소.

  • +0

    알았어. 괜찮은지 확인해. 문자열 이름에 대한 roll_no, POINTER 및 포인터 자체의 주소는 연속적으로 실제로 저장됩니다. 문자열 자체는 메모리에 저장되어 있습니다. 맞습니까? – adijo

    +0

    예. * 문자열 * 자체와 * 포인터 *가 가리키는 * int *는 메모리의 다른 곳에 있습니다. –

    +0

    내가 이것을했을 때 : printf ("% p \ n % p \ n % p", & s.roll_no, & s.name, & s.pointer); roll_no의 주소, 문자열에 대한 포인터의 주소 및 포인터의 주소가 연속적이었습니다. 하지만 당신이 지금 말한 것은 이것과 모순됩니다. ** 문자열과 int에 대한 포인터의 주소 만 연속적입니다. ** – adijo