포인터를 인자로 넘기고 함수에서 포인터를 조작할때.

rereretry의 이미지

코드는 아래와 같습니다.

#include <stdio.h>

char g_g = 5;

void f(void *p)
{
    p = &g_g;
}

main()
{

    int* p =NULL;

    f((char*)p);

    printf("p %d\n", *p);

}

또는

#include <stdio.h>

char g_g = 5;

void f(char *p)
{
    p = &g_g;
}

main()
{

    char* p =NULL;

    f(p);

    printf("p %d\n", *p);

}

둘다 세그멘테이션 에러를 부르더군요.
왜 이럴까요?
전 그냥 단지 포인터 인자를 입력받는 함수를 만들고
거기에 제가 원하는 것의 함수를 붙여서 보내고 싶었을 뿐인데

int *p
int a;

p = &a;

요건 되는데 저건 왜 안될까요?

고민하다하다 부랴부랴 가입하고 로그인 하고
결국 질문을 했습니다.

포인터의 어떤 또다른 심오한 문제때문인거 같은데
내공 참 제가 후집니다. OTL

답변 달아주심 정말 감사할께요.

익명 사용자의 이미지

함수 호출시에는 해당 변수의 값 자체가 복사됩니다.
f 내에서 p 가 가리키는 주소를 변경하더라도 그것은 p의 복사본을 바꾸는 것이지 p 자체를 바꾸는게 아닙니다.

의도하신데로 바꾸면

void f(  void **p) {
    *p = &g_g ;
}

main()
{

    int* p =NULL;

    f((char**)&p);

    printf("p %d\n", *p);

}

대충 이렇게 될 겁니다.

eminency의 이미지

C에서는 함수 인자를 Call by value로 넘깁니다.
포인터를 넘기는 것은 Call by reference가 아니라 주소값을 Call by value로 넘김으로써 Call by reference의 효과를 본다고 생각하시면 됩니다.

노루가 사냥꾼의 손에서 벗어나는 것 같이, 새가 그물치는 자의 손에서 벗어나는 것 같이 스스로 구원하라 -잠언 6:5

rereretry의 이미지

말씀하셨던대로 그렇군요.
다른 자료들을 좀 봤거든요.

근데 어느초보님 코드 대로 해보았더니.

f((char**)&p); 요부분에서

gcc에서는

Quote:
warning: passing arg 1 of `f' from incompatible pointer type

이런경고만 뜨지만

g++에서는

Quote:
error: invalid conversion from `char**' to `void**'
이렇게 아예 에러로 처리를 해버리네요.

void가 형에 관해서 일반적으로 처리하겠다는 의미가 아니였나요?

생각할수록 복잡해집니다. 쿨럭.

익명 사용자의 이미지

C++에서는 void*형으로부터 다른 형으로의, 혹은 그 반대로의 암시적인 형변환을 지원하지 않습니다. 따라서 g++에서 발생하는 에러는 당연한 것입니다.

참고로, 서로 다른 형의 포인터 변수끼리 같은 메모리 표현을 가지고 있다고 가정하고 프로그램을 짜는 것은 별로 바람직하지 않습니다. 포인터 끼리의 형변환은 void*형으로, 혹은 그 반대의 변환이 아닌 이상 삼가하는 편이 좋습니다.

댓글 달기

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