"class 내의 static 배열을 초기화 할때의 문제"

1. 소스
#include
#include
class song
{
public
static int count;
static int i_arr[10];
};
int songcount = 0;
int songi_arr[10];
void main(void)
{
int i = 0;
class song * t_song;
/* 주목1 */
memset((void *)songi_arr, (int)1, sizeof(int)*10);
for(i = 0; i < 10; i ++)
{
t_song = new song;
cout<<"song.count"<count<<"i_arr"<i_arr
[i]<
++t_song->count;
delete t_song;
}
/*주목 2*/
(songi_arr[1] == 1) ? cout<<"OK"<
}
2. 출력결과
2- 1)위 프로그램 대로 하면.
song.count0i_arr16843009
song.count1i_arr16843009
song.count2i_arr16843009
song.count3i_arr16843009
song.count4i_arr16843009
song.count5i_arr16843009
song.count6i_arr16843009
song.count7i_arr16843009
song.count8i_arr16843009
song.count9i_arr16843009
NOT
2-2) 주목 1에서 (int)1 -> (int)0 하고
주목 2에서 (songi_arr[i] == 1)-->(songi_arr[i] == 0)으로 하면
song.count0i_arr0
song.count1i_arr0
song.count2i_arr0
song.count3i_arr0
song.count4i_arr0
song.count5i_arr0
song.count6i_arr0
song.count7i_arr0
song.count8i_arr0
song.count9i_arr0
OK
3. 질문
결과 2-1)과 2-2)를 보면, i_arr[10]을 0으로 초기화 하는 경우에는 제대
로 초기화 되지만 i_arr[0]을 1로 초기화 하는 경우에는 초기화에 실패하
고 엉뚱한 숫자가 들어가는 것을 알수 있습니다.
3-1) 왜 이런 결과가 생기는 것인지 원인을 알고 싶습니다.
3-2) i_arr[10]을 0이 아닌 다른 값으로 초기화하려면 어떻게 해야 할까
요?
이 질문에 대한 고수님들의 현명한 답변을 기대합니다.
^____________________________^;
Re: "class 내의 static 배열을 초기화 할때의 문제"
결과 2-1)과 2-2)를 보면, i_arr[10]을 0으로 초기화 하는 경우에는 제대
로 초기화 되지만 i_arr[0]을 1로 초기화 하는 경우에는 초기화에 실패하
고 엉뚱한 숫자가 들어가는 것을 알수 있습니다.
3-1) 왜 이런 결과가 생기는 것인지 원인을 알고 싶습니다.
>> static 멤버 변수의 초기화는
class이름변수이름 = 값
이나
class이름배열이름 = {초기값1, 초기값2,...};
의 식으로 초기화가 되어야 합니다.
memset은 메뉴얼을 살펴본 결과
-------------------------------------------------------------
SYNOPSIS
#include
void *memset(void *s, int c, size_t n);
-------------------------------------------------------------
DESCRIPTION
The memset() function operates as efficiently as possible on memory
areas. It does not check for overflow of any receiving memory area.
Specifically, memset() sets the first n bytes in memory area s to
the value of c (converted to an unsigned char). It returns s.
-------------------------------------------------------------
(int)1 이라고 인자를 넣어도, 내부에서 unsigned char로 바꾸어져서,
지정된 버퍼에 지정된 값으로 채우는 듯 해서 그런 값이 되는 것 같습니
다.
3-2) i_arr[10]을 0이 아닌 다른 값으로 초기화하려면 어떻게 해야 할까
요?
int songi_arr[10] = {1,2,3,4,5,6,7,};
이런식으로 배열 초기화를 해 주면 되겠죠~ ^ ^
글쎄요...이유는 알겠는데..다른 방법이 없을까요?
-------------------------------------------------------------
DESCRIPTION
The memset() function operates as efficiently as possible on memory
areas. It does not check for overflow of any receiving memory area.
Specifically, memset() sets the first n bytes in memory area s to
the value of c (converted to an unsigned char). It returns s.
-------------------------------------------------------------
(int)1 이라고 인자를 넣어도, 내부에서 unsigned char로 바꾸어져서,
지정된 버퍼에 지정된 값으로 채우는 듯 해서 그런 값이 되는 것 같습니
다.
3-2) i_arr[10]을 0이 아닌 다른 값으로 초기화하려면 어떻게 해야 할까
요?
int songi_arr[10] = {1,2,3,4,5,6,7,};
이런식으로 배열 초기화를 해 주면 되겠죠~ ^ ^
___________________________________________________________________
여기서는 사실 그렇게 해도 상관없습니다.
다만...
배열의 크기가 10000이라고 가정한다면 님이 제시하신 그런 초기화란 것
은 무의미 하겠죠.
더군다나 만약 동적으로 할당된 데이타를 특정값으로 초기화 하려고 할때
는 더욱더 힘들어 질 것 같군요.
(무식하게 for문 돌리면 될 것도 같지만...이건 답이 아니라고 봅니다)
어쨋든 한큐에 해결할 수 있는 Smart한 방법이 없을까요?
가령...unsigned char형으로 변환되어도 integer형으로 인식했을때 원하
는 값이 나오는 방법이라든가 아니면 memset말고 다른 함수가 존재한다
면 더욱 좋겠구요...
고수님들의 현명하신 답변 부탁드립니다.
^___________________^
std::fill 알고리듬을 사용하세요.
김경태 wrote..
-------------------------------------------------------------
DESCRIPTION
The memset() function operates as efficiently as possible on memory
areas. It does not check for overflow of any receiving memory area.
Specifically, memset() sets the first n bytes in memory area s to
the value of c (converted to an unsigned char). It returns s.
-------------------------------------------------------------
(int)1 이라고 인자를 넣어도, 내부에서 unsigned char로 바꾸어져서,
지정된 버퍼에 지정된 값으로 채우는 듯 해서 그런 값이 되는 것 같습니
다.
좀더 자세히 설명하겠습니다.
memset이 string.h에 있는 문자열 조작 함수라는 사실에 유의하십시오.
memset(i_arr, c, sizeof(int) * 10);
라고 되어 있어도,
memset은 i_arr를 무조건 unsigned char 배열로 인식합니다.
sizeof(unsigned char) = 8bit 만큼 무조건 unsigned char인 c 값으로 초
기화해버리죠.
int가 32bit이므로 i_arr의 원소 하나당 4번의 복사가 일어납니다.
그러므로 님의 원하는 값과는 전혀다른 값인
0x01010101 = 16843009 가 되어버리죠.
인제 아시겠죠?
3-2) i_arr[10]을 0이 아닌 다른 값으로 초기화하려면 어떻게 해야 할까
요?
int songi_arr[10] = {1,2,3,4,5,6,7,};
이런식으로 배열 초기화를 해 주면 되겠죠~ ^ ^
___________________________________________________________________
여기서는 사실 그렇게 해도 상관없습니다.
다만...
배열의 크기가 10000이라고 가정한다면 님이 제시하신 그런 초기화란 것
은 무의미 하겠죠.
더군다나 만약 동적으로 할당된 데이타를 특정값으로 초기화 하려고 할 때
는 더욱더 힘들어 질 것 같군요.
(무식하게 for문 돌리면 될 것도 같지만...이건 답이 아니라고 봅니다)
별로 무식한 방법은 아닙니다. memset도 내부적으로 루프를 돌려서 초기화하는 겁니다.
어쨋든 한큐에 해결할 수 있는 Smart한 방법이 없을까요?
가령...unsigned char형으로 변환되어도 integer형으로 인식했을때 원하
는 값이 나오는 방법이라든가 아니면 memset말고 다른 함수가 존재한다
면 더욱 좋겠구요...
for 루프를 돌리는 것을 무식하게(?) 여기신다면,
"한큐에 해결할 수 있는 Smart한 방법"을 소개하죠.
ANSI C++ STL(Standard Template Library)에 있는 fill 알고리듬을 사용하는 방법입니다.
// ANSI C++ 표준에서는 .h를 안씁니다. 예를 들어 memset을 쓰려면 으로 표기해야 합니다.
#include
#pragma hdrstop // 이건 BC++에서 precompiled header를 위한 지시어. 다른 컴파일러는 쓰지 마세요.
#include // STL 헤더는 precompiled header로 놓을 수 없습니다.
#include // 템플릿 라이브러리이기 때문이죠.
using namespace std; // 이 선언도 항상 필요합니다.
int i_arr[10];
int main()
{
fill(&i_arr[0], &i_arr[10], 1);
// fill(i_arr, i_arr + 10, 1) 또는 fill_n(i_arr, 10, 1) 라고 써도 됩니다.
copy(&i_arr[0], &i_arr[10], ostream_iterator(cout, "\n"));
// i_arr를 cout으로 "한 큐에" 출력하는 "Smart한" 방법
return 0;
}
고맙습니다. ^^;
과연 스마트하군요. ^^;
한데 속도는 얼마나 나올지...(이런 소리하면 돌날라오겠죠?)
암튼 고맙습니다. 감사 감사...
Re^5: 고맙습니다. ^^;
김경태 wrote..
과연 스마트하군요. ^^;
한데 속도는 얼마나 나올지...(이런 소리하면 돌날라오겠죠?)
속도는 for 루프를 돌리는 것과 거의 비슷할 겁니다.
fill등의 STL 알고리듬은 루프를 템플릿 함수로 추상화한 겁니다.
댓글 달기