char 형의 크기는 영원히 1byte 일까요?

매그넘의 이미지

제목이 조금은 자극적일까요?..

문자열 처리와 관련된 일을 자주하다 보니.. 인터넷상의 다른 소스들도 많이 참고를 하고 있는데..

아래와 같은..코드가 있는데.. 어느것이.. 제대로된 코드인지 판단을 부탁드리겠습니다.

char *str = "test string";
char *copy_str;
 
//copy_str 에 str을 복사하기 위해서 malloc 을 한다.
copy_str = (char *)malloc(sizeof(char) * strlen(str) + 1);    // 1번 코드
 
copy_str = (Char *)malloc(sizeof(char) * (strlen(str) + 1 ) );  // 2번 코드
 
strcpy(copy_str, str);

위의 코드에서 malloc 하는 부분을..두가지를 작성을 했는데.. 1번과 2번..어느것이.맞는 건지..^^

char 형의 크기가 1byte 이면.. 1번, 2번 모두 같은 크기의 메모리공간이 확보합니다.

하지만 char 형의 크기가 1byte 를 넘게 되면.. 2번 코드가 정확히 필요한 공간을 확보하게 되죠..

그래서 궁금하게 되었네요..^^ char 형의 크기는 언제까지 1byte 일까??...

제가 작성한 코드들을 뒤져보니.. 은근히 1번 형태로 작성된게 많이 있네요..(char 는 무조건 1byte이다!!)..

개중에는 sizeof(char) 를 아예 생략해 버린 코드들도..나오고 있구요..^^..

고수님들의..고견 부탁드리겠습니다!!!..

narusas의 이미지

현재 C99 까지는 1byte 이지만 언젠가는 1BYTE가 아니라 유니코드 1글자를 나타내는 시대가 오겠죠.

ㅡ,.ㅡ;;의 이미지

그런시대는 안올것같군요...

----------------------------------------------------------------------------
C Library Development Project


----------------------------------------------------------------------------

ssehoony의 이미지

네/아니오 로 대답하기 힘든거지만 아마도 영원히 1바이트 일겁니다.
만약 그 이상이 필요하면 wchar 같은 것이 추가되는 형태가 될듯합니다.

이렇게 예상하는 것은 64비트 cpu가 없을 때 일반적인 가르침을 보면
16비트 플랫폼에서는 int 가 16비트 이며, 32비트 플랫폼에서는 int 가 32비트라고 했습니다.
그렇다면 당연히 64비트 플랫폼에서는 int 가 64비트여야 하지만
64비트에 대해서는 여러가지 처리방식이 존재합니다.
이유는 하위호환문제 때문인데요.
위와 비슷한 이유로 char 역시 그런 호환문제로 2바이트 이상으로 변경될 것 같지가 않네요.

envia의 이미지

일단 현재 sizeof(char)은 무조건 1입니다. C에서 1바이트는 CHAR_BITS개의 비트로 이루어지며, char도 같은 수의 비트로 이루어집니다. (여기서 CHAR_BITS는 8보다 크거나 같고, 바이트나 char 모두 기본 문자 집합의 원소를 저장할 수 있어야 합니다.) char이 커지려면 바이트도 커져야 하고, 바이트가 커지면 char도 따라서 커집니다. CHAR_BITS는 <limits.h>에 들어 있습니다. 참고로 비트 필드를 제외한 다른 모든 자료형은 바이트 단위로 이루어집니다. sizeof(char)의 배수로 이루어지는 것이지요. 따라서 char이 16비트로 이루어진다면 8비트로 이루어진 자료형은 사용할 수 없게 됩니다.

그러면 앞으로도 계속 그럴까요? 그럴 것으로 보입니다. 무엇보다도 현재 sizeof(char)은 1이라고 표준 문서와 모든 C 교재에 나와 있고 많은 프로그래머들이 그것에 의존해 프로그램을 작성하고 있는데 표준을 관리하는 위원회가 sizeof(char)의 값을 바꿀 리 없습니다. 위원회는 일단 작성된 프로그램은 거의 수정할 필요가 없도록 배려하면서 C 표준을 고쳐왔습니다.

그래서 위의 경우 copy_str = malloc(strlen(str)+1); 만으로도 충분하고, 나머지는 코딩 스타일의 문제입니다.

It is essential, if man is not to be compelled to have recourse, as a last resort, to rebellion against tyranny and oppression, that human rights should be protected by the rule of law.
[Universal Declaration of Human Rights]

----

It is essential, if man is not to be compelled to have recourse, as a last resort, to rebellion against tyranny and oppression, that human rights should be protected by the rule of law.
[Universal Declaration of Human Rights]

narusas의 이미지

나중에는 byte 라는 데이터타입이 추가되고 char은 확장될 거라고 생각합니다.

점점 유니코드에 대한 중요성이 커지고 있기때문에 어느시점이 되면 유니코드를 기본지원하지 않으면 않되게 될겁니다.

물론 호환성 때문에 char자체가 변경되지는 않을 가능성이 높지요.
ssehoony님이 말씀하시것 처럼 별도의 키워드를 통해 확장해 나갈거라고 생각합니다.
wchar이나 uchar 정도가 되지 않을까 생각합니다만.. 모르죠. char이 그냥 unicode를 지원하게 변경될지도요. 가능성은 매우 낮겠지만요 ^^

ㅡ,.ㅡ;;의 이미지

일단 1byte크기가 1char크기와같다 라는개념은 아무리세월이 흘러도 바뀔리가 없을것으로봅니다.
char의 바이트수를 늘린다하더라도 유니코드를 완전히 지원할수 없으며
근본적인개념을 바뀌가면서까지 그렇게 하지 않으리라봅니다.
정확장의 필요성이 있을때는 char의 바이트를 늘리는것이 아니라 byte의 bit 수를 늘리겠죠..

----------------------------------------------------------------------------
C Library Development Project


----------------------------------------------------------------------------

서지훈의 이미지

C/C++언어에 한정한다면 이게 별로 바끼지 않고 그대로 갈듯합니다.
그러나 이미 자바에서는 byte가 있고 char은 2byte이죠.
그리고 앞으로 새로 나오게될 랭귀지들은 char를 2byte로 해서 많이들 나오지 않을까요?
그러나 영미권 국가에서는 이게 불필요 할 수도 이겠지만 포팅이 편해 줄 수도 있으니.
그리고 요즘처럼 넉넉한 메모리에서 너무 쪼잔할 필요도 없고 말이죠 ㅎㅎ;

추신_즐거운 설 되세요 ~~~

#include <com.h> <beer.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

죠커의 이미지

그나저나 여전히 많은 사람들이 1 바이트를 octet으로 생각하더군요. 게다가 유니코드도 2 옥텟 문자열로 착각하시는 것 같습니다. 유니코드는 어느 정도의 용량이 필요하다고 규정되어 있지 않습니다. UTF-8부터 UTF-32까지 서로 다른 옥텟을 사용하고 있습니다. 게다가 UTF-16이 필요하다면 wide character가 제공되고 있습니다. wide character가 환경마다 구현이 다른 것이 문제입니다. 하지만 엄연히 따진다면 char 형 조차도 환경마다 다릅니다.

- CN의 낙서장 / HanIRC:#CN

superkkt의 이미지

"1바이트가 꼭 8비트는 아니다" 인건가요? 이것에 대해서 좀 더 자세히 설명해주실 수 있나요? 아니면 관련된 웹사이트라도 알려주시면 감사하겠습니다.

======================
BLOG : http://superkkt.com

======================
BLOG : http://superkkt.com

죠커의 이미지

KLDP의 글의 링크로 대신하겠습니다.

http://kldp.org/node/44167
http://kldp.org/node/77754
http://kldp.org/node/39915

1바이트는 8비트가 아니라 글자 하나를 표기할 수 있는 크기를 의미하는 것입니다.

- CN의 낙서장 / HanIRC:#CN

전웅의 이미지


>
> 제목이 조금은 자극적일까요?..

"영원히"라는 단어 때문에 좀 자극적이긴 하네요. 물론, "영원히"로
"C 언어가 존재하는 동안"을 의미하신 것이라 믿습니다.

> 문자열 처리와 관련된 일을 자주하다 보니.. 인터넷상의 다른 소스들도 많이 참고를 하고 있는데..
> 아래와 같은..코드가 있는데.. 어느것이.. 제대로된 코드인지 판단을 부탁드리겠습니다.
>
> char *str = "test string";
> char *copy_str;
>
> //copy_str 에 str을 복사하기 위해서 malloc 을 한다.
> copy_str = (char *)malloc(sizeof(char) * strlen(str) + 1); // 1번 코드
> copy_str = (Char *)malloc(sizeof(char) * (strlen(str) + 1 ) ); // 2번 코드
> strcpy(copy_str, str);
>
> 위의 코드에서 malloc 하는 부분을..두가지를 작성을 했는데.. 1번과 2번..어느것이.맞는 건지..^^
> char 형의 크기가 1byte 이면.. 1번, 2번 모두 같은 크기의 메모리공간이 확보합니다.
> 하지만 char 형의 크기가 1byte 를 넘게 되면.. 2번 코드가 정확히 필요한 공간을 확보하게 되죠..
> 그래서 궁금하게 되었네요..^^ char 형의 크기는 언제까지 1byte 일까??...
> 제가 작성한 코드들을 뒤져보니.. 은근히 1번 형태로 작성된게 많이 있네요..(char 는 무조건 1byte이다!!)..
> 개중에는 sizeof(char) 를 아예 생략해 버린 코드들도..나오고 있구요..^^..
> 고수님들의..고견 부탁드리겠습니다!!!..
>

고수는 아닙니다만, 스타일이나 의미를 배제하고 결과만을 놓고 본다면 둘
모두 동일하며, 이는 (위에서 언급한 의미로) "영원히" 참입니다.

char 형의 정의 자체가 byte 와 밀접하게 관련되어 있고 sizeof 연산자의
단위가 byte 이기 때문에 어쩔 수 없이 항상 1이 될 수밖에 없습니다.
이와 같은 정의는 깨뜨리기에는 너무 견고한 것이며, 이를 깨뜨릴 경우
문제를 일으키는 코드가 한두개가 아니기 때문에 섣불리 바꿀 수 있는
부분이 아닙니다. 따라서 두 코드 모두 정확히 동일한 동작을 한다고 보장
할 수 있습니다.

컴퓨터 분야의 고질적인 문제인 byte-character conflict (하나의 byte 로
하나의 character 를 표현할 수 있다는 가정이 더 이상 참일 수 없게 되는
문제) 해결을 위해 C 언어는 character 와 byte 를 분리하기 보다는 그냥
모호함 속에서 견뎌 나가기를 택했습니다. 가장 큰 원인은 위에서도 언급
했지만 기존 코드에 대한 하위 호환성입니다.

실제 표준화 초기에 byte 형을 새로 도입하고 char 형을 (현재 wchar_t 형
이 그런 것처럼) "문자"를 위한 type 으로 분리하자는 주장도 있었습니다.
하지만, 거절되어 현재 상태는 char 가 사실상 byte 형과 single-byte
문자를 위한 데이터형 역할을 모두 하고, 모호하게도 C 표준 상에서
"character" 라는 용어가 ("byte"라는 의미를 포함) 무려 7가지 다른 문맥
에서 사용되는 결과를 낳게 되었습니다.

대형 character set 지원을 위해서는 기본적으로 multibyte character 와
wide character 의 개념으로도 충분하지만 (따라서 ISO 10646 지원 역시
이미 C95 정도로도 충분합니다), ISO 10646 에 대한 보다 이식성 높은
지원을 위해 현재 TR 을 통해 새로운 type name 을 새로 추가하려고 계획
하고 있습니다. 중요한 사실은 그와 같은 TR 이 현 표준의 ISO 10646 지원
이 미흡해 진행되고 있는 것이 아니라, 보다 specific 한 지원을 위해
진행되고 있다는 사실입니다.

더불어 기본 개념만 놓고 본다면, char 형으로 ISO 10646 같은 대형
character set 을 지원할 수 없는 것도 아닙니다. 다른 조건이 만족한다는
전제 아래 구현체에서 char 형의 크기를 늘리면 그만이기 때문입니다.
물론, 그와 같은 경우에는 (C 언어의 입장에서) char 형이 n바이트
(n >= 2) 가 되는 것이 아니라 해당 구현체에서 한 byte 의 크기가 커지는
것입니다 - 따라서 여전히 sizeof(char) == 1 이 됩니다.

개인적인 경험을 고려했을 때 "스타일" 문제를 이야기하자면 다음과 같이
작성하는 것을 추천합니다.

copy_str = malloc(sizeof(*copy_str) * N);

C 언어일 경우 malloc 의 반환값 캐스트는 불필요하며, N 에는 필요한
개수를 명시해 주면 됩니다.

제가 개인적으로 했던 실수를 돌이켜보면, 문자의 "개수"에 대한 개념이
너무 강하다보니 wide character N개를 위한 공간을 할당할 때 생각없이
다음과 같이 작성하던 경우가 있었습니다.

wchar_t *copy_str;
assert(sizeof(wchar_t) >= 2);
...
copy_str = malloc(N+1);

위에서 보인 스타일은 이런 경우에도 문제를 예방하는데 도움이 될 수
있습니다.

--
Jun, Woong (woong at icu.ac.kr)
Web: http://www.woong.org (서버 공사중)

--
Jun, Woong (woong at gmail.com)
http://www.woong.org

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.