2013-08-20 4 views
1

C (또는 C++)의 링크 된 목록 구현에서 포인터 변수의 노드 및 수명은 얼마입니까? 예를 들면 :C의 링크 된 목록 구현에서 노드의 크기 및 수명은 어떻게됩니까?

struct node 
{ 
    int data; 
    struct node *next; 
}*ptr=NULL; 

지금은 노드의 크기를 알고 싶어 : 그것은, 4 바이트이며, 만약 그렇다면, 어떻게? 둘째, 포인터가 얼마나 오래 지속됩니까? 마지막으로 *ptr을 인스턴스 변수 또는 데이터 멤버 또는 개체로 호출하는 것이 적절합니까?

+2

크기는 구조용 포장재에 따라 전적으로 플랫폼에 따라 다릅니다. 'sizeof (* ptr)'는 컴파일 타임에 실제 크기로 평가할 것입니다 ('sizeof (struct node)'도 마찬가지입니다). 그리고 그것은 당신이 살도록 내버려 두는 한 오래 산다. 마지막으로'next'는 포인터가 아니라 객체입니다. 이를 멤버 변수, 인스턴스 변수, 인스턴스 멤버 변수라고 할 수 있습니다. 비트가 계속됩니다. – WhozCraig

+1

질문에 정의 된대로 노드의 크기는 일반적으로 32 비트 플랫폼에서는 8 바이트이고, 64 비트 플랫폼에서는 12 바이트 이상이 보통 16 바이트입니다. 16 비트 포인터와 16 비트'int '타입을 가진 16 비트 컴파일러를 찾았다면 길이가 4 바이트 일 수도 있지만 그렇지 않은 경우도 있습니다. 언급 한 크기에 대한 보증은 없습니다. 그러나 대부분의 컴파일러는 내가 제공 한 답 중 하나를 생성합니다. –

+0

@rosemary 그것은 질문의 험난한 사람입니다. 나는 당신이 잠들지 않고 그 답을 읽을 수 있기를 바랍니다. 다음 번에는 질문을 작은 덩어리로 나누고 작은 답변을 얻을 수 있는지 알아보십시오. :) –

답변

0

크기는 컴파일 타임 작업입니다. 노드는 구조체입니다. 따라서 노드의 크기는 구조체의 모든 멤버 크기의 합계입니다. 그래서 정수와 포인터가 있습니다. 노드 크기는 정수 크기 + 포인터 크기입니다. 수명 : 메모리가 동적으로 할당됩니다. 당신이 자유를 부를 때까지, 마디는 산다. u가 삭제 작업을 수행하면 Good 프로그래머 스타일을 사용하여 해당 노드에 할당 된 메모리를 해제합니다.

+2

받아 들여지는 동안, 이것은 실제로 잘못된 것입니다. 노드의 크기는 메모리 정렬 경계를 유지하는 데 필요한 모든 패딩 크기와 모든 패딩의 합입니다 .__ 이것의 좋은 예는'integer + pointer' 구조체는'char + pointer' 구조체와 같은 양의 메모리를 차지할 가능성이 높습니다. –

+0

그리고 경계는 아키텍처에 따라 다르며 컴파일러가 경계에 맞게 정렬하는 방법은 컴파일러에 따라 다를 수 있습니다. – lsiebert

+0

예, 패딩을 고려해야합니다. 예를 들어, char 및 integer는 구조체 멤버입니다. char의 크기는 1 바이트이고 정수는 4 바이트입니다. 그러나 구조의 크기는 5가되지 않습니다. 패딩 때문에 5 이상이됩니다. –

4

일반적으로 노드 크기를 알 수 없습니다. 그러나 특정 플랫폼 및 라이브러리 세트에 대해 컴파일 타임에 노드 크기를 알 수 있습니다.

sizeof(struct node) 

당신에게 노드의 크기를 말할 것이다. 노드 내의 모든 구성원의 실제 크기가 결합되지 않을 수 있습니다. 경우에 따라 구조체 내의 멤버를 적절한 작업에 필요한 메모리 정렬 경계에 맞추려면 패딩이 필요합니다.

또한 포인터에는 특정 크기가 없습니다. 그들은 필요한 메모리 주소를 수용하기에 충분히 크지 만 만족시켜야하는 유일한 요구 사항입니다. 32 비트 및 64 비트 환경에서 포인터 크기에는 큰 차이가 있으며 동일한 하드웨어에서 지원되는 두 비트 환경 사이를 이동하지 않더라도 다른 하드웨어 플랫폼 은 포인터 값을 저장하는 데 필요한 메모리 요구 사항이 다릅니다.

"포인터를 저장하는 4 바이트"를 얻는 곳은 C를 사용하는 모든 컴퓨터가 32 비트 코드 만 실행할 수있는 펜티엄 칩 제품군의 인텔 CPU라는 오해에서 비롯된 것입니다. 그 당시에는 진실이 아닌 가정이었으며 지금도 똑같이 사실이 아닙니다.

구조적 배열은 올바른 메모리 정렬을 위해 배열 요소 간 패딩을 요구할 수 있습니다. 결과적으로 구조체의 크기를 알더라도 X 요소의 배열이 X * sizeof(struct node) 바이트의 메모리 영역에 맞는지 확인할 수 없습니다.

sizeof(...)을 사용하여 찾으려는 답변을 찾으십시오. 그러나 크기를 차지하려는 거의 모든 것이 sizeof(...) 운영자에 있는지 확인하십시오.

포인터의 수명까지는 프로그램이 실행되는 한 오래 유지됩니다. 그러나 node->next에 저장된 값은 실제로 의미있는 주소를 참조하지 않을 수도 있습니다. node->next은 주소를 보유하도록 설계되었지만 node->nextstruct node의 요구 사항을 충족시키는 비트 패턴의 시작을 지정하지 않는 주소를 가리킬 수있는 방법이 너무 많습니다.

이 C 언어의 "문제"는 포인터 유형 작업을 불가능하게함으로써 C 언어의 "개선"을 의미하는 이후 언어에서 어느 정도 수정되었습니다. 대신에 언어는 포인터 연산의 안전한 하위 집합을 허용했기 때문에 실제로 포인터가 없었습니다 (그래서 포인터라고 불렀습니다). Java와 C#은 두 가지 언어가 있지만 포인터에 대한 진정한 위험한 작업을 거부하는 언어가 많이 있습니다.

포인터가 변수의 인스턴스를 호출하는 것은 실제로 메모리 주소를 보유하는 변수이기 때문에 적절하지 않습니다. 보유하고있는 메모리 주소에는 포인터의 "유형"을 만족시키는 비트 패턴이 포함되어야한다는 엄격한 요구 사항은 없습니다. 이것은 C와 호환되도록 보존 된 C 유산 중 하나입니다.또한 인스턴스 변수는 객체 지향 용어를 제안하는 경향이 있으며 C는 객체 지향 보장을 제공 할 수 없으므로 객체 지향 프로그래밍 용어를 C에 적용하는 것은 적절하지 않습니다.

마찬가지로 구조체는 클래스가 아니며 구조체의 멤버는 클래스 멤버와 약간 다른 규칙을 따릅니다. 가장 큰 "약간 다른"규칙은 구조체의 멤버가 일반적으로 공개적으로 액세스 할 수 있다는 것입니다. 실제로 프로그램의 나머지 부분에서 구조체의 선언을 숨기지 않도록주의를 기울이지 않는 한 (C 체조가 많이 필요합니다. 당신의 프로그램은 여전히 ​​작동합니다).

+0

thnks @ 답답한 답 : – rosemary

+0

@rosemary 언제든지 도와 주셔서 감사합니다. –

2
  1. 노드의 크기는 컴퓨터와 컴파일러에 따라 다릅니다. 그것을 얻으려면 sizeof(struct node);을 사용하십시오. 4 바이트가 아닙니다. 32 비트 환 경에서는 8 (int의 경우 4 바이트이고 struct node *의 경우 4 바이트)입니다.

  2. ptr은 프로그램 실행 중에 만 존재합니다. ptr은 전역 변수입니다. *ptrptr 점은 상기 메모리 수단 동안

  3. ptr인스턴스 변수이다.

관련 문제