[완료] Realloc 과 Illegal Seek 에 관한 질문입니다

wanderer의 이미지

안녕하세요

C 프로그래밍 중 사소한(?) 문제가 발생해서 의견을 듣고자 작성합니다

다음과 같은 코드가 있을 경우

char* ptr = (char *) malloc(sizeof(char)*10);
perror("Blah~");
ptr = (char *) realloc(ptr, sizeof(char)*10);
perror("Blah~");
...
ptr = (char *) realloc(ptr, sizeof(char)*10);
perror("Blah~");
free(ptr);
ptr = NULL;

위와 같은 코드를 C99 호환의 컴파일러를 작성하고 실행하면

첫번째 malloc 의 경우 errno 가 Success 로 정상 출력이 되지만

realloc 의 경우 errno 가 설정되어 Illegal Seek 이 출력됩니다

실제 valgrind 와 같은 툴을 사용해서 memory leak 의 발생여부를 확인해도 문제가 되지 않고

realloc 후에 pointer 에 무언가 저장 한다고 해도 문제 없이 작동하는 것을 확인했습니다

저런 경우 Illegal Seek 과 같은 메시지는 무시해도 되는지 알려 주시면 감사하겠습니다

솔직히 왜 Illegal Seek 이 발생하는지 더 궁금하기도 합니다

( man page 의 경우 메모리가 부족할 경우만 에러값이 설정된다고 하던데... )

덧붙여 하나 궁금한것이 Realloc 의 경우 size_t 에 들어가는 size 가

위와 같이 이전 메모리 size 와 같을 경우 C99 에 위배 되는지 알려주시면 감사하겠습니다

ymir의 이미지

errno 는 해당 함수가 명백히 에러를 리턴하는 경우 errno 를 세팅하기로 약속되어 있는 경우에만 유효합니다.
각각의 함수가 아무런 에러를 리턴하지 않았는데, errno 를 찍어보는 것은 무의미합니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

wanderer의 이미지

그러면 다음과 같은 코드에서

ptr = (char *) realloc(ptr, sizeof(char)*10);
if(errno) {
perror("Blah~");
}

와 같은 방법으로는 에러를 검출하지 못한다는 말과 동일한것입니까?

답변 감사합니다

cinsk의 이미지

errno를 보기 전에, realloc()의 return value가 NULL인지 확인해야합니다.
NULL이 아닐 경우, errno는 의미없습니다.

--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/

madman93의 이미지

NULL if the request fails.
라는 문장이 나오니
실제 ptr 값이 NULL 이면 errno 값을 보게 되겠죠

if (ptr == NULL)
{
   perror("Blah~");
}

대충 이정도 되겠네요

malloc 도 마찬가지 이겠군요

man malloc 의 RETURN VALUES 를 보면
아래와 같군요

if successful, calloc(), malloc(), realloc(), reallocf(), and valloc()
     functions return a pointer to allocated memory.  If there is an error,
     they return a NULL pointer and set errno to ENOMEM.

---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

---------------------------------------------
git init
git add .
git commit -am "project init"
---------------------------------------------

jick의 이미지

음 그런데 제가 주워듣기로는 함수가 에러를 내지 않았을 경우 errno의 값은 바뀌지 말아야 한다는 게 표준이라고 알고 있습니다만... 좀 이상하긴 하네요.

(뭐 제가 잘못 알고 있을 수도 있습니다.)

ymir의 이미지

많은 라이브러리 함수들이, 포인터를 리턴하는 경우에는 실패시 NULL, 정수형을 리턴하는 경우에는 실패시 -1 을 리턴합니다.
리턴값을 체크해서, 이 함수가 실패했을 경우에 왜 실패했는지 확인하기 위해 참고하는게 errno 입니다.
man page 마다 RETURN VALUES 라는 섹션이 있을텐데, 이 부분을 미리 잘 살펴두시는게 좋을겁니다.

그리고 라이브러리 함수들 역시 내부적으로 다른 라이브러리 또는 시스템 콜을 호출합니다.
그때 에러가 발생하더라도 로직에 따라 성공을 리턴할 수도 있고, 에러 리턴시 다른 errno 를 설정할 수도 있습니다.
따라서, errno 를 처리하기 전에 다른 함수들을 호출해야 하는 경우가 있다면, 미리 저장을 해 놓는 편이 안전합니다.

errno 가 내부적으로 어디쯤에서 세팅되었는지 보시려면.. strace 로 찍어보시면 될겁니다.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

댓글 달기

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