[완료]char * 배열의 크기를 알아내는 법 질문 드립니다.

poplinux의 이미지

다음과 같이 배열을 선언한 후

char buf[1024]

void size(char *array) 함수로 다음과 같이 넘겼습니다.

size(buf);

이렇게 할 경우 size() 함수안에서 buf의 크기를 알아보고 싶을 땐 어떤 식으로 처리를 해야 할까요?

sizeof()를 사용할 경우엔 1byte 로 결과값이 나와 버립니다.

robo872의 이미지

C 배열은 길이를 가지고 있지 않습니다.
컴파일 할때만 배열의 길이를 알고 실행시에는 아무런 정보가 없습니다.
따라서 저런 함수로는 알 수가 없습니다.
배열 길이는 보통 아래와 같은 매크로를 사용합니다.
#define ARRAY_LEN(X) (sizeof(X)/sizeof(X[0]))

익명 사용자의 이미지

> C 배열은 길이를 가지고 있지 않습니다.
> 컴파일 할때만 배열의 길이를 알고 실행시에는 아무런 정보가 없습니다.

무슨 말도 안되는 말씀을...
배열은 길이가 있고 실행시에도 길이를 알 수 있습니다.

ironboy의 이미지

설명 좀 해주세요... 편법으로라도 알아낼 수 있다면 나중에라도 좋겠는데요..

익명 사용자의 이미지

이 사람이 큰일날 소리를...
배열의 길이를 구하는 것은 위에 어떤분이 적어주신 방법밖에 안됩니다.

#define ARRAY_LEN(X) (sizeof(X)/sizeof(X[0]))

* 참고로 X[0]는 (X)[0]로 고쳐야 됩니다.

sizeof를 이용한 것이므로 당연히 컴파일 할때만 배열의 크기를 알 수 있습니다.

게다가 인자로 주어지는 X의 타입이 반드시 array of ... 이어야만 합니다.
보통 배열은 array of ... 에서 pointer to ... 로 변하는 경향이 있으므로,
함부로 쓰다간 size of pointer/size of (*X)가 되어 된통 당하는 일이 있습니다.

배열의 길이는 프로그래머가 따로 관리를 해주는 것이 원칙적으로 맞습니다.

정태영의 이미지

어떻게 발악해서 알아낸다면 알아낼 수야 있을지 모르겠지만... 호환성도 떨어지고 이래저래 문제가 많을 것 같습니다. 그리고 참고로 sizeof 는 함수가 아니라 매크로입니다. 컴파일 타임에 sizeof(...) 의 값은 상수로 정해지게 됩니다.

malloc 등의 소스를 참고한다면 (호환성은 떨어지겠지만) 동적으로 할당된 메모리에 대한 사이즈를 알아내는 것이 가능할 것 같지만 앞에서 얘기했듯이 malloc, free 등의 구현이 다 같지 않을테므로 호환성에 문제가 있을 것입니다.

다른 분들이 얘기하셨듯이 그냥 길이를 따로 저장하는 것이 맘도 편하고 호환성에도 문제가 없는 방법이 되지 않을까 합니다.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

익명 사용자의 이미지

> 어떻게 발악해서 알아낸다면 알아낼 수야 있을지 모르겠지만... 호환성도 떨어지고 이래저래 문제가 많을 것 같습니다.
#define ARRAY_LEN(X) (sizeof(X)/sizeof(X[0]))
이것도 발악이라면 할 말 없구요.

void func(char* p)
{
ARRAY_LEN(p);
}

char p[10];
fund(p);

이런 걸 갖고 그러시는 모양인데 이건 당연히 안되죠.
왜냐하면 func 안에서 p는 배열이 아니라 포인터이기 때문입니다.

> 그리고 참고로 sizeof 는 함수가 아니라 매크로입니다.
전에도 이런 얘기 하시더만 아직도 그러시네요.
sizeof는 함수도 매크로도 아니고 연산자(operator)입니다.

C99 표준
6.5.3 Unary operators
6.5.3.4 The sizeof operator

> 컴파일 타임에 sizeof(...) 의 값은 상수로 정해지게 됩니다.
누가 아니라고 했나요?
저는 컴파일 타임에는 알 수 있지만 런타임에는 알 수 없다는 얘기가 틀리다고 한 겁니다.

jick의 이미지

Quote:
#define ARRAY_LEN(X) (sizeof(X)/sizeof(X[0]))

(중략)

> 컴파일 타임에 sizeof(...) 의 값은 상수로 정해지게 됩니다.
누가 아니라고 했나요?
저는 컴파일 타임에는 알 수 있지만 런타임에는 알 수 없다는 얘기가 틀리다고 한 겁니다.

이런 걸 "컴파일 타임에만 알 수 있다."라고 표현합니다. sizeof 안에 쓴 지정한 이름의 배열에 대해서만 값이 나오니까, 런타임에 임의의 배열에 대해서 실행할 수 없는 거죠. 위에 쓰신 ARRAY_LEN macro도 매크로의 인자가 컴파일 타임에 결정되어야 하고, 그거 하나에 대해서만 값을 알 수 있지 임의의 배열에 대해서 알 수 없죠. 예를 들어 ARRAY_LEN(flag ? array1 : array2) 이런 식으로 쓸 수 없습니다.

런타임에 알 수 있다는 건 예를 들면 함수로 임의의 배열 X를 던져줬을 때 이 배열 X의 크기를 함수 내에서 알 수 있는가? 이런 걸 런타임에 알 수 있다고 표현하는 겁니다.

익명 사용자의 이미지

> 이런 걸 "컴파일 타임에만 알 수 있다."라고 표현합니다.
이런 걸 "컴파일 타임에도 알 수 있다."라고 표현합니다.

>런타임에 알 수 있다는 건 예를 들면 함수로 임의의 배열 X를 던져줬을 때 이 배열 X의 크기를 함수 내에서 알 수 있는가? 이런 걸 런타임에 알 수 있다고 표현하는 겁니다.
이런 걸 런타임에만 알 수 있다고 표현하는 겁니다.

익명 사용자의 이미지

ARRAY_LEN(1 ? array1 : array2)

이건 컴파일 타임에 매크로의 인자가 결정되는데 안되는지 되는지좀 설명해 주십시오 jick님.

다른 분들은 끼어들지 말고 jick님만 설명해 주십시오.

jick의 이미지

자세한 설명은 생략한다. - 김성모.

런타임에 된다고 주장하고 싶으면 런타임에 되는 예제를 들고와야죠. 컴파일타임에 안되는 예제를 들고오면 뭐합니까? 쯧.

익명 사용자의 이미지

왜 안되는지 설명을 해보시라니까요?

컴파일 해보고 된다 안된다 말하는건 원숭이도 할 수 있습니다.

jick의 이미지

원숭이는 컴파일해보라고 하면 신나서 잘 합니다. (뭐, 최소한 컴파일을 해보고 된다 안된다 말할 수 있는 수준의 원숭이라면 그렇겠죠.)

근데 사람은 좀 더 똑똑해서 뭔가 떡고물이 떨어지지 않으면 잘 움직이지 않죠. 설명해 드릴 용의는 있는데, 일단 계좌번호 불러드릴까요? 얼마 주실라우?

* 자 과연 몇 point나 깎일 것인가!

lifthrasiir의 이미지

sizeof가 항상 컴파일 타임에 결정되는 '상수'인 것은 아닙니다. 한 가지 예를 들면...

size_t func(int k)
{
        int arr[k+3];
        return sizeof arr;
}
 
// ...
printf("%d\n", func(11));

따라서 sizeof의 계산은 런타임에만 수행되게 됩니다. (아마 sizeof(int) * (k + 3)이겠지요...) ISO/IEC 9898:1999에서 상수식(6.6 Constant expressions)으로 정의한 수식에서도 이러한 sizeof는 빠져 있습니다:

"6. An integer constant expression shall have integer type and shall only have operands that are integer constants, enumeration constants, character constants, sizeof expressions whose results are integer constants, and floating constants that are the immediate operands of casts. Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the sizeof operator." (강조는 제가 했음)

하지만 이런 경우가 아닌 이상 sizeof의 계산은 컴파일 타임에 수행될 수도 있으며, 보통 그렇게들 합니다. (일반적인 경우 이 상황을 '컴파일 타임에 수행된다'라고 표현하죠?!)

poplinux의 이미지

네. 감사합니다.

========================
조직 : E.L.D(Embedded Linux Developer/Designer)
블로그 : poplinux@tistory.com
카페 : cafe.naver.com/poplinux

임베디드 리눅스 관련 프리렌서 지향

superkkt의 이미지

size() 함수 안에서는 인자로 받은 배열의 사이즈를 알아낼 방법이 없습니다. 보통 배열을 인자로 받는 함수의 경우에는 두번째 인자로 해당 배열의 사이즈를 넘겨받도록 만듭니다. 자세한 내용은 아래 페이지를 읽어보세요.

http://cinsk.org/cfaqs/html/node8.html#6.21

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

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

litdream의 이미지

대표적으로 array size 를 따로 변수에 정해서 유지해야 하는 예제가 되겠네요.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main()
{
  char *arr[10] = { "Hello", "World", };  // prefixed array size
  printf("I hope this is 2: %d\n", sizeof(arr)/sizeof(arr[0]));
 
  return 0;
}

삽질의 대마왕...

삽질의 대마왕...

익명 사용자의 이미지

arr 사이즈가 10이라서 10이라고 출력하는데 뭐가 이상합니까?
혹시 님이 생각하시는건 이거 아닙니까?

char *arr[] = { "Hello", "World", }; // prefixed array size
printf("I hope this is 2: %d\n", sizeof(arr)/sizeof(arr[0]));

댓글 달기

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