malloc에 대한 질문입니다.

bellus의 이미지

안녕하세요
fundamentals of data structure in C 를 읽고 있는데요
list를 설명하는 부분에서

struct list_node *list_pointer ;
struct list_node  {
   char data[4] ; 
   list_pointer link ;
} ;

...

ptr = (list-pointer)malloc(sizeof(list_node)) ;

이걸 설명하면서

Quote:
The type cast is unneccessary in ANSI C, but we include it here for portability

라고 하네요.
안시C에서는 타입캐스트가 필요없다는 말인데, 그렇담 타입캐스트를 하지 않아도, 즉 ptr = malloc(....) 만 해도 ptr->char나 ptr->link로 바로 사용 가능하다는 말인가요?

소중한 가르침 기다립니다~[/code]

cinsk의 이미지

> 타입캐스트가 필요없다는 말인데

void *는 다른 type의 pointer로 자동으로 형변환됩니다.
따라서 malloc()이 리턴하는 void *는 어떤 포인터에도 casting없이 대입될 수 있습니다. (그렇다고 모든 casting이 필요없는 것은 아닙니다.)

... wrote:
The type cast is unneccessary in ANSI C, but we include it here for portability

이식성이라하면 void *가 없는 pre-ANSI C compiler 용 또는 C++용 compiler용으로 만들기 위해서라고 생각할 수 있습니다.

pre-ANSI C, 좀 더 정확히 말해 void *가 존재하지 않는 compiler의 경우, 흔히 void *를 unsigned char *로 쓰기도 하는데, 이 경우 casting이 필요할 수 있습니다. (제 추측입니다.)

또한 C++에서는 C에서보다 엄격한 형변환을 수행하기 때문에 malloc()의 return value를 casting없이 다른 형 pointer 변수에 대입할 수 없습니다. 예를 들어 C++에서 아래 코드는 에러입니다:

float *p = malloc(sizeof(*p));

제대로 하자면 아래 세 개 문장 중 하나를 써야 합니다.

float *p = (float *)malloc(sizeof(*p));
float *p = static_cast<float *>(malloc(sizeof(*p)));
float *p = reinterpret_cast<float *>(malloc(sizeof(*p)));

그럼 이만 참고가 되었기를...

전웅의 이미지

cinsk wrote:
> 타입캐스트가 필요없다는 말인데

void *는 다른 type의 pointer로 자동으로 형변환됩니다.
따라서 malloc()이 리턴하는 void *는 어떤 포인터에도 casting없이 대입될 수 있습니다. (그렇다고 모든 casting이 필요없는 것은 아닙니다.)

void * 를 object pointer 로 대입하는 경우라면 모든 정상적인 경우에 강
제 형변환이 필요 없습니다. C 로 프로그램을 작성하는 과정에 포인터형의
강제 형변환이 들어 있다면 해당 부분을 유심히 살펴봐야 합니다 - 의도적
이며 올바른 경우일 수도 있겠지만, 이식성을 갖지 못하는 행동일 가능성이
큽니다. 표준은 null pointer 혹은 문자형 포인터와 관련된 경우를 제외하
면 포인터와 관련된 강제 형변환에 그리 아름다운 의미를 부여하지 않습니
다. 따라서 특히 malloc() 과 관련된 경우라면 강제 형변환을 사용하지 않
는 것이 이점 (추후 유지 보수에 유리하다, malloc() 의 적절한 원형이 제
공되지 않은 경우 이를 알 수 있다 등) 이 더 많습니다.

cinsk wrote:
... wrote:
The type cast is unneccessary in ANSI C, but we include it here for portability

이식성이라하면 void *가 없는 pre-ANSI C compiler 용 또는 C++용 compiler용으로 만들기 위해서라고 생각할 수 있습니다.

pre-ANSI C, 좀 더 정확히 말해 void *가 존재하지 않는 compiler의 경우, 흔히 void *를 unsigned char *로 쓰기도 하는데, 이 경우 casting이 필요할 수 있습니다. (제 추측입니다.)

ANSI C 를 언급하고 책 자체가 "in C" 인 것을 보아 pre-standard C 를 고
려한 문장 같습니다 - 물론, 지금 시점에서는 무시하셔도 좋습니다. cinsk
님께서 말씀하신대로 void 형 자체가 표준에 의해 새로 추가된 것이고, 따
라서 void * 에 generic pointer 의 의미를 부여한 것도 표준에 의해 이루
어진 것입니다.

과거에는 generic pointer 의 의미로 문자 포인터 (char *) 를 사용했습니
다만, 피치못할 사정으로 (캐스트를 매번 요구할 것이냐, 아니면 유용한 진
단 메시지를 사실상 막을 것이냐의 문제) void * 에 대입 호환성을 갖는
generic pointer 의 의미를 부여하고, char * 는 순수한 문자 포인터의 의
미를 갖도록 했습니다. (구구절절한 이야기는, IT 백두대간 C 언어 p.359)

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