"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이 아닌 다른 값으로 초기화하려면 어떻게 해야 할까
요?

이 질문에 대한 고수님들의 현명한 답변을 기대합니다.

^____________________________^;

익명 사용자의 이미지

결과 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말고 다른 함수가 존재한다
면 더욱 좋겠구요...

고수님들의 현명하신 답변 부탁드립니다.

^___________________^

익명 사용자의 이미지

김경태 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;
}

익명 사용자의 이미지

과연 스마트하군요. ^^;

한데 속도는 얼마나 나올지...(이런 소리하면 돌날라오겠죠?)

암튼 고맙습니다. 감사 감사...

익명 사용자의 이미지

김경태 wrote..
과연 스마트하군요. ^^;

한데 속도는 얼마나 나올지...(이런 소리하면 돌날라오겠죠?)

속도는 for 루프를 돌리는 것과 거의 비슷할 겁니다.

fill등의 STL 알고리듬은 루프를 템플릿 함수로 추상화한 겁니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.