NULL포인터 호출문제.....

devscott의 이미지

먼저 간단한 소스를 봐주세요..

class base
{
public:
base() { printf ("construct\n"); };

~base() { printf("desctruct\n"); };

public:
void func() { printf("this %x \n", this); };
}

int main()
{
base aa; // construct 찍힘
base *p = 0;
printf("0x%x \n", p ); // 0x0 찍힘

delete p; // 0번지를 지울려고 했기때문에 segment fualt 가 날것으로 예상하지만 아무변화없음

p++;
printf("0x%x \n", p ); // 0x1 찍힘..
p->func(); // this 0x1 찍힘

base *pp = new base; // construct 찍힘
pp = 0;
pp->func(); //this 0x0 찍힘

delete pp; // desctruct 가 안찍힘..

}

제 생각엔 당연히 null 포인터 호출시 segment fault 가 유발될것으로 생각했는데
이게 무슨 일인가요..
널 포인터를 증가시켜서 호출했더니... 이것도 호출되고.

도움 부탁드립니다..

ifree의 이미지

delete p ->; 0번지를 지우는게 아니고 메모리만 해제함(p는 생성조차 되지 않아서 delete 할 것도 없네요).
p++ ; p 값은 정상적으로 작동함.

base *pp = new base; // construct 찍힘
pp = 0;
-> pp 값을 바꾸었기 때문에 생성되지 않은 객체로서 delete 가 되지 않음.

whiterz의 이미지

size가 0인 메모리를 free할 때 library 단에서 아마 무시할겁니다.

p->func() 에서 p가 잘못된 값인데도 동작하는 이유는 func()내에서 dynamic(run-time에 할당되는) object를 사용하지 않기 때문에,
virtual function table 같은 걸 사용하지 않을테고, 결과적으로 C++ 컴파일러가 p->func()를 compile time에
정할 수 있기 때문에 바로 해당 function으로 binding하기 때문일겁니다. ^^

ktd2004의 이미지

p = 0;
delete p;

NULL 포인터를 delete하는 것은 전혀 문제가 없는 것으로 알고 있습니다.
아마 Effective C++에 언급된 것으로 기억이 납니다.

p->func();

func 함수 내부에서 구조체의 멤버변수에 write하도록 하면 아마 에러가 문제가 발생할 것으로 보입니다.

func은 다음과 같이 호출되겠죠.
하지만 null인 this를 func내부에서 전혀 사용하지 않으니까 문제가 발생하지 않는 것 같습니다.

func( base *this);

위와 마찬가지로 null에 대한 delete 호출은 어떠한 일도 하지 않는 것 같습니다.

pp = 0;
delete pp;
pastime의 이미지

p->func();

위의 경우 func()가 (가상 함수가 아닌) 일반 함수라면
함수 호출 시점에 p에 대한 접근이 일어나지 않는 것 같습니다.
(p의 타입 정보를 통해 name mangling을 수행하여
compile time에 함수의 주소를 미리 계산해 두고
run time에는 그냥 해당 함수를 호출만 하는 것 같습니다.)

func()를 가상 함수로 선언하면 원하는? 결과를 얻으실 수 있을 듯..

lowid의 이미지

비슷한 문제이긴한데

printf("OK: %p\n", &(*((char*)0)));
printf("Segmentation Fault: %d\n", (*((char*)0)));

첫번째 에서도 똑같이 0를 참조하긴 하니까 오류가 나야하는거 아닌가요?

---------------------------------------------
아치리눅스좀 써주세요
-> 아치리눅스 유저 좀 꼬셔오세요. 1인당 10명!

댓글 달기

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