포인터에 관해 질문드립니다...

맹고이의 이미지

항상 당연한 듯이 사용해 오다가 갑자기 궁금해져서 질문드립니다.

C에서 라이브러리 함수들을 보면 리턴값이 구조체의 포인터라던지

문자열의 첫주소를 돌려주는 것들이 있는데... 그 함수 안에서는

malloc을 부르는 것 처럼... 동적 할당이 되는 건가요?

만약 그렇다면... 메모리 해제를 시켜줘야 될 것 같은데

함수 호출 뒤에 사용자가 따로 free를 해주는 그런 함수는 본 적이 없으니

제 짧은 지식으로는 어디에 어떻게 저장을 하는 건지 잘 모르겠습니다.

답변 부탁드립니다.

bitneer의 이미지

static variable

좋은하루되세요

맹고이의 이미지

bitneer wrote:
static variable

좋은하루되세요

함수 안에 static으로 구조체가 선언 되어 있었다면

이후에 같은 함수를 다시 호출하면 예전에 리턴값의 내용도

바뀌어 버리는 게 아닌가요?

그리고... 문자열이라면, 처음부터 고정된 공간에 적어서

주소를 리턴해 주는 것인가요?

자세히 알려주셨으면 좋았으련만... ^^;

singlet의 이미지

매뉴얼을 읽으세요. 경우에 따라 다릅니다. 예를 두 개 들어보죠.

strdup() 함수의 man page 에는 아래의 설명이 있습니다.

The strdup() function returns a pointer to a new string which is a
duplicate of the string s. Memory for the new string is obtained with
malloc(3), and can be freed with free(3).

ctime() 함수의 man page 에는 다음 설명이 있고요.

The four functions acstime(), ctime(), gmtime() and localtime() return
a pointer to static data and hence are not thread-safe.

즉 strdup() 가 돌려준 포인터는 반드시 free() 하셔야 하고, 반대로 ctime() 이 돌려준 포인터는 절대 free() 하시면 안됩니다. 모든 함수에 일괄적으로 통하는 한 길은 없습니다.

cedar의 이미지

맹고이 wrote:

함수 안에 static으로 구조체가 선언 되어 있었다면

이후에 같은 함수를 다시 호출하면 예전에 리턴값의 내용도

바뀌어 버리는 게 아닌가요?

그리고... 문자열이라면, 처음부터 고정된 공간에 적어서

주소를 리턴해 주는 것인가요?

이런 함수의 대표적인 예가 ctime()이죠. 그러므로 재호출하기 전에 리턴값을 미리 복사해 두어야 합니다.

singlet wrote:

매뉴얼을 읽으세요. 경우에 따라 다릅니다. 예를 두 개 들어보죠.

strdup() 함수의 man page 에는 아래의 설명이 있습니다.

The strdup() function returns a pointer to a new string which is a
duplicate of the string s. Memory for the new string is obtained with
malloc(3), and can be freed with free(3).

ctime() 함수의 man page 에는 다음 설명이 있고요.

The four functions acstime(), ctime(), gmtime() and localtime() return
a pointer to static data and hence are not thread-safe.

즉 strdup() 가 돌려준 포인터는 반드시 free() 하셔야 하고, 반대로 ctime() 이 돌려준 포인터는 절대 free() 하시면 안됩니다. 모든 함수에 일괄적으로 통하는 한 길은 없습니다.

ctime()과 같이 ANSI 표준 라이브러리 함수에서는 리턴 포인터를 free()하는 경우는 없습니다.
반면에 strdup()과 같은 ANSI 표준이 아닌, POSIX나 WIN32 등의 함수에서는 반드시 free()를 해줘야 하는 함수들이 있죠. 표준 함수가 아닐 경우에는 반드시 매뉴얼 페이지를 읽어보세요.

맹고이의 이미지

답변 감사드립니다.

그렇다면 C 라이브러리 함수에서

구조체 포인터나 문자열을 리턴하는 함수 중,

함수인자에 user-supplied buffer가 없는 함수들은

모두 static 변수에 저장해놓고 주소를 리턴해주는

thread-safe하지 않는 함수겠군요...

kslee80의 이미지

맹고이 wrote:
답변 감사드립니다.

그렇다면 C 라이브러리 함수에서

구조체 포인터나 문자열을 리턴하는 함수 중,

함수인자에 user-supplied buffer가 없는 함수들은

모두 static 변수에 저장해놓고 주소를 리턴해주는

thread-safe하지 않는 함수겠군요...

*_r 같은 이름을 가진 함수들은 Thread-safe 하지 않은 함수들을
Thread-safe 하게 재작성한 함수들입니다.

이 함수들의 Prototype 를 보시면 아시겠지만,
원래 함수와는 틀리게 버퍼(?)를
아규먼트로 요구합니다.

그리고 문자열을 리턴하는 함수중 strerror() 은 Thread-safe 합니다.

pynoos의 이미지

맹고이 wrote:
그렇다면 C 라이브러리 함수에서

구조체 포인터나 문자열을 리턴하는 함수 중,

함수인자에 user-supplied buffer가 없는 함수들은

모두 static 변수에 저장해놓고 주소를 리턴해주는

thread-safe하지 않는 함수겠군요...

항상 그런 것만은 아닙니다. static 변수로 pthread_key_create 에서 생성된 키를 가지고 부르는 thread 마다 다른 값이 나오도록 바꾼 thread-safe 한 버전도 있습니다.

또한, thread-safe 뿐 아니라, 복사하지 않고 두번 호출하는 일을 하지않아야 되는 경우가 더 흔히 만나는 오류인것 같습니다.

#include<netinet/in.h>

int main()
{
        struct in_addr a,b;
        a.s_addr = inet_addr("172.16.100.1");
        b.s_addr = inet_addr("172.16.100.2");

        printf("%s\n%s", inet_ntoa(a), inet_ntoa(b) );
        return 0;
}

$ ./a
172.16.100.1
172.16.100.1
맹고이의 이미지

음... 그렇군요. ^^;

답변 달아주신 분들께 감사드립니다~

댓글 달기

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