동적으로 할당된 변수 크기 구하기

mips의 이미지

char *c = NULL;
char b[10];
 
c = (char*)malloc(sizeof(char)*100);
 
printf("%d\n", sizeof(c));
printf("%d\n", sizeof(b));

위의 코드에서 c의 크기는 4로 나오고 b의 크기는 10으로 나옵니다.
c가 100이 나오길 기대하고 있었는데, 4로 나오는 걸 보면 아마 포인터의 크기를 리턴한것 같은데,
b는 왜 10이 나올까요?

동적으로 할당된 변수(여기서는 c)의 크기(100 바이트)를 알아낼 방법은 없을까요?

irondog의 이미지

변수 c를 포인터로 선언 했으니 포인터 사이즈인 4가 나오는 것이 정상입니다.
C++라면 모를까 C라면 글쎄요.. 동적으로 할당받은 메모리에 값으로 정해서 넣지 않으면 알 수 없을 겁니다.

Nadia85의 이미지

그럼 C++에서는 알 수 있나요?

irondog의 이미지

c++에서 malloc()로 만들어진 동적 메모리의 양을 알 수 있다는 뜻은 아니었고요.
형선언이 안됀 더미 메모리의 사이즈는 아무래도 알 수 있는 방법이 없을 것 같네요.

c에서도 될런지 확인을 안해봤는데, 이렇게 형선언을 해서 메모리를 할당하면
알 수 있습니다.

typedef char  mychar[100];
mychar  *p = new mychar[0];
 
int size1 = sizeof (*p);
int size2 = sizeof (p);

여기서 size1은 4로 포인터값 그대로일테고, size2는 100이 되겠죠.

김정균의 이미지

ㅎㅎ 기억도 안나는데 제가 이런 답변을 달아 놓은 적이 있었네요

https://kldp.org/comment/546280#comment-546280

요약하면 링크하신 _msize는 windows에서, linux 에서는 malloc_usable_size 를 사용할 수 있지만 절대적이지는 않다.

그리고 이 얘기들은 아래 댓글에 보면 선지자들께서 이미 답변을 다 달아 놓으셨습니다. :)

klyx의 이미지

배열이름의 경우는 sizeof연산자가 배열의 전체 크기를 반환해줍니다.

하지만 동적할당한 경우는 그저 포인터일 뿐이므로(그게 배열인지 포인터인지 알길이 없죠) 포인터 자체의 크기만 반환해줍니다.

동적할당된 배열의 크기를 알아야 하는 경우라면, 처음부터 그 크기가 저장된 값을 함께 넘겨주어야 합니다.

다만 널로 종료되는 문자열의 경우는 널의 위치를 조사하거나 strlen함수로 (배열 전체가 아니라) 문자열의 길이를 알 수 있습니다.

imposno의 이미지

배열의 이름 또한 포인터 아닌가요?

말씀대로 포인터를 이용한 sizeof연산자의 반환값은 포인터 자체의 크기만을 반환해줘야 하기에

배열이름에 대한 sizeof연산자의 반환값은 포인터의 크기가 반환되는것 아닌가해서요.(물론 배열의 전체사이즈를 반환하지만)

그냥 궁금해서요 ^^

lateau의 이미지

> 배열의 이름 또한 포인터 아닌가요?

배열의 이름과 포인터는 동작은 닮았지만 실제로는 별개의 물건입니다.
설명할수는 있지만 이해시키기가 어려워 그냥 '똑같다'라고 표현해버리는 책이 많은 것 같아요.

--
I think to myself...what a emerging world.

--
I think to myself...what a emerging world.

imposno의 이미지

> 동작은 닮았지만 별개의 물건이다.

동작이 실제로 다른 부분도 있다는 말씀이신가요? 제가 무지해서요.
한가지 예만 들어주시면 좋을것 같습니다.
감사합니다.

kaeri17의 이미지

예를들어 int a[100] 의 a는 int [100] 의 타입입니다. 따라서 sizeof(a)를 하면 400이 나오는 것이고요(32bit에서), C언어적으로 편의를 위해 a의 값은 &(a[0]) 와 같은 겁니다. 이와 반대로 정말 포인터 int *a는 int*타입 인 것이고요.

neocoin의 이미지

C spec 을 검색하다보니.

괜찮은 FAQ가 잡히네요.

Question 6.2 - But I heard that char a[] was identical to char *a.

elysium의 이미지

메모리 할당 함수를 자체적으로 다시 재정의해서 사용하시면 될 것입니다.
glibc의 malloc 구현을 참고하세요.

아주 간단하게 생각하면 요청한 크기보다 더 크게 할당해서 앞부분에 할당받은 크기를 저장하고
그 뒷부분의 주소를 리턴하는 함수를 작성하여 mymalloc() 이런 식으로 사용하셔도 될 것같은데요.

coathanger의 이미지

정보 감사합니다.

shmhlove의 이미지

==========================================================================

malloc.h에 정의된 size_t _msize( void *p ); 함수를 이용하면 됩니다.
예제 첨부할께요~
※ 참고로 windows.h에 정의된 HeapSize(...) 함수도 크기를 알아올수 있답니다~

==========================================================================

int *pInt = (int*)malloc( sizeof(int) * 100 );
printf("크기 %d\n", _msize((void*)pInt) / sizeof(int));
free(pInt);

==========================================================================

nthroot의 이미지

_msize()는 윈도우 CRT 함수입니다.

------식은이 처------
길이 끝나는 저기엔 아무 것도 없어요. 희망이고 나발이고 아무 것도 없어.

pastime의 이미지

malloc_usable_size() 함수를 이용할 수도 있습니다.

댓글 달기

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