int a[1];
은 정수형 데이터 하나를 저장하는 공간을 스택에 만듭니다. 이건
int b;에서도 마찬가지 입니다.
그런데 문제는 a라는 포인터상수 입니다.
이녀석은 분명 4바이트(운영체제에 따라 2바이트)의 공간을 차지하는
상수 입니다. 이 상수는 어디에 만들어질까요.
char *ptr = "abcde";라고 선언했을 경우 ptr은 스택에 4바이트를 차지하는
변수로 만들어지고 "abcde"는 힙영영에 6바이트로 만들어지죠.
이것과 같다고 봅니다. a[1]에서의 a는 힙영역에 생성이 될겁니다. :idea:
Do you think that's the air you are breathing now?
상수는 heap에 만들어지지 않습니다.
굳이 따지자면 상수는 코드 (세그먼트) 에 *박혀* 있습니다.
예로 드신
char *ptr = "abcde";
에서 "abcde" 는 데이터 영역에 생성되며,
ptr은 함수 안이라면 말씀하신대로 스택에 생성됩니다.
함수 내에서 정의된
char arr[6] = "abcde";
의 경우, "abcde"는 데이터영역에 생성되며,
함수호출시 스택의 해당 공간으로 복사됩니다.
이 경우 arr 이 문제일텐데,
printf("%s\n", arr);
이라는 문장을 수행하려면 arr 값을 넘겨야 할텐데,
이 값은 스택이나 데이터영역에 있지 않고,
힙에는 더더욱이나 저장되어 있지 않습니다.
이 값은 코드에 존재합니다.
컴파일시에 C는, arr로 대표되는 char 6 바이트가 스택내의 어느 위치에
저장될지를 알 수가 있습니다. (사실은 컴파일러가 그 위치를 지정해 주어야 겠지요.) 따라서 컴파일러는 arr의 값을 다른 곳에 저장하는 것이 아니라
그 값을 코드에 직접 포함하고 있는 것입니다.
위 어셈블리코드는
Linux host 2.4.2-2wl #1 금 6월 8 05:21:58 KST 2001 i686 unknown,
gcc 2.96
에서 생성된 것입니다. 어셈블리 문법은 조금 틀리지만 역시나 arr의 값이 코드에 직접 들어있는 것을 확인하실 수 있습니다.
[code:1]char a[1];char b;[/cod
에서 a는 포인터이므로 4바이트를 차지할 터이고
a[1] 는 1바이트를 가지고 있을겁니다.
그리고 b는 1바이트만 차지할겁니다.
a의 타입은 '배열'입니다. 포인터가
a의 타입은 '배열'입니다. 포인터가 아닙니다.
C/C++에서 '배열'이나 '함수' 등의 타입은 non-scalar 타입으로,
scalar로써 식 내에 쓰일 경우 scalar 값인 '배열 포인터', '함수 포인터' 등으로 각각 변환되어 처리될 뿐이지,
그 자체가 포인터는 아닙니다.
다시 말해,
에서 sizeof array 는 200이지, sizeof (char *) 와 같은 값이 아니라는 것입니다.
===
http://cafe.daum.net/codeinside
a가 공간을 차지하나요?
a[1]
에서 a는 포인터상수로 알고있습니다.
처음부터 할당된 값의 상수도 아니구요.
그런데 4바이트를 차지(?)하나요?
궁금하네요. 초보라서 ^^
Re: a가 공간을 차지하나요?
a는 어드레스를 의미하며, 32 bit 기계에서 4byte 입니다.
fprintf(stderr, "sizeof(&a) -> %d", sizeof(&a));
와 같이 주소의 크기를 찍어보세요.
Re: a가 공간을 차지하나요?
논리적인 크기는 4바이트가 맞습니다만,
포인터 상수는 메모리 공간을 차지하지는 않습니다.
Orion Project : http://orionids.org
[re] 기초질문입니다만, char a[1] 과 char a
"char a[1];"이건 1개의 char형 값을 가진 배열을 생성한것입니다.
또한 이 배열의 첫번째 원소인 a[0]은 "char a;"라고 선언한 변수
와 동일합니다.
또한 배열 a의 주소를 알고자 할때는 본 자신의 배열이름이름이며,
하지만 "char a;"의 주소를 알고자 할때는 & 연산자를 앞에 붙여야만
합니다.
sizeof 연산자를 이용해 데이터 객체의 크기를 리턴을 해보면
"char a;"의 sizeof a는 1byte를 반환하지만,
"char a[1];"의 sizeof a또한 1byte를 반환합니다.
여기서 중요한 것은,
배열의 sizeof는 배열 첨자의 개수 x sizeof(데이타형) 라는 것입니다.
"char a[4];"의 sizeof a는 4byte를 반환하겠죠?
하지만, "char a[4];"의 sizeof &a[1]은 1byte일까요? 아닙니다.
a[1]이란 1byte의 데이타를 가르키고 있는 포인터의 크기이므로
4byte가 정답입니다. 이상입니다 ^^
포인터상수 어디에 생기나..
일반적으로 상수를 사용하면 그 상수는 힙에 저장됩니다.
int a[1];
은 정수형 데이터 하나를 저장하는 공간을 스택에 만듭니다. 이건
int b;에서도 마찬가지 입니다.
그런데 문제는 a라는 포인터상수 입니다.
이녀석은 분명 4바이트(운영체제에 따라 2바이트)의 공간을 차지하는
상수 입니다. 이 상수는 어디에 만들어질까요.
char *ptr = "abcde";라고 선언했을 경우 ptr은 스택에 4바이트를 차지하는
변수로 만들어지고 "abcde"는 힙영영에 6바이트로 만들어지죠.
이것과 같다고 봅니다. a[1]에서의 a는 힙영역에 생성이 될겁니다. :idea:
Do you think that's the air you are breathing now?
"abcde" 는 상수라서 스택에 생성될텐데요?
"abcde" 는 상수라서 스택에 생성될텐데요?
Re: 포인터상수 어디에 생기나..
상수는 heap에 만들어지지 않습니다.
굳이 따지자면 상수는 코드 (세그먼트) 에 *박혀* 있습니다.
예로 드신
char *ptr = "abcde";
에서 "abcde" 는 데이터 영역에 생성되며,
ptr은 함수 안이라면 말씀하신대로 스택에 생성됩니다.
함수 내에서 정의된
char arr[6] = "abcde";
의 경우, "abcde"는 데이터영역에 생성되며,
함수호출시 스택의 해당 공간으로 복사됩니다.
이 경우 arr 이 문제일텐데,
printf("%s\n", arr);
이라는 문장을 수행하려면 arr 값을 넘겨야 할텐데,
이 값은 스택이나 데이터영역에 있지 않고,
힙에는 더더욱이나 저장되어 있지 않습니다.
이 값은 코드에 존재합니다.
컴파일시에 C는, arr로 대표되는 char 6 바이트가 스택내의 어느 위치에
저장될지를 알 수가 있습니다. (사실은 컴파일러가 그 위치를 지정해 주어야 겠지요.) 따라서 컴파일러는 arr의 값을 다른 곳에 저장하는 것이 아니라
그 값을 코드에 직접 포함하고 있는 것입니다.
다음은 C 코드와 이에 대응되서 생성된 어셈블리코드입니다.
(SunOS host 5.7 Generic_106541-23 sun4u sparc SUNW,Ultra-80,
gcc 3.0.3)
이 중 arr의 값이 전달되는 부분은 call printf, 0
바로 앞 부분에 있는 add %fp, -40, %o1 입니다.
즉, -40이 fp (frame pointer. 해당 함수호출의 스택 프레임) 와 합해져서 값을 곧바로 만들어 낸 것입니다. 즉, arr의 값은 일반적인 변수들과는 달리 데이터나 스택 영역에 저장되지 않지만 굳이 말하자면 코드에 박혀있다고 말할 수 있습니다.
위 어셈블리코드는
Linux host 2.4.2-2wl #1 금 6월 8 05:21:58 KST 2001 i686 unknown,
gcc 2.96
에서 생성된 것입니다. 어셈블리 문법은 조금 틀리지만 역시나 arr의 값이 코드에 직접 들어있는 것을 확인하실 수 있습니다.
조금 다르면서도 비슷한 얘기로,
인 경우 상수값 5도 코드에 직접 들어가 있습니다.
어셈블리의 어드레싱 모드 중 immediate 모드가 여기에 해당되겠습니다.
최종호님 감사..
제가 부정확하게 알고있는 것 정정해주셔서 감사요.. (_ _)
Do you think that's the air you are breathing now?
댓글 달기