return by index or return by value ?

sleepbysleep의 이미지

보통 저의 경우 메모리 누수현상과 거림직함으로 항상 확보된 메모리의 포인터를 넘겨 주어서 아래와 같이 처리 합니다.

typedef struct { double real, imag; } comp;

void comp_prod(comp *c, comp *a, comp *b) {
c->real = a->real * b->real - a->imag * b->imag;
c->imag = a->real * b->imag + b->real * a->imag;
}

그런데 다음과 같이 넘겨 주어도 되더 군요.
제 생각으로는 안되거나 에러가 나야 하는것아닌지 하는 생각이 드네요 보통 리턴 값은 레지스터에 담아서 넘겨 지지 않나요?
이경우 2개의 인자를 동시에 넘겨 주는건 어떻게 생각해야 하나요?
그리고 메모리 이동은 어떻게 되는지 아시는지?

comp comp_prod(comp a, comp b) {
comp c;

c.real = a.real * b.real - a.imag * b.imag;
c.imag = a.real * b.imag + b.real * a.imag;

return c;
}

익명 사용자의 이미지

후자가 되기는 하지만, 스트럭쳐가 크면(스트럭쳐에 포함된 구성원이 지금 2개인데, 한 100개쯤된다면,... 예로는 별로군요... ㅎㅎ) 메모리 전달(값전달)을 위한 파라메터 개수가 많아지므로 비효율적일 수 있습니다.
전자의 경우 포인터 sizeof(포인터)만 파라메터로 넘어갔다가 넘어오니까, 유리한 점이 있습니다.

pynoos의 이미지

i386 linux 상의 gcc의 경우 위의 예에서 comp 구조체의 복사가 일어나긴하지만, 넘어가는 크기는 comp 만한 크기가 아니고 comp에 대한 포인터가 넘어갑니다.
함수 리턴을 위한 공간도 미리 확보하고 포인터를 넘겨주기 때문에 돌아올 때도 포인터만 받아옵니다.

Fe.head의 이미지

gcc로 해놓을걸 보니.(struct 약간 변경)

typedef struct { int a,b,c,d,e; } comp;
comp comp_prod(comp a, comp b)
{
    comp f_c;
    f_c.a = 0;
    return f_c;
}

void a()
{
 comp a,b,c;
 
 // 어셈블로 변환할때 주소값을 확인하기 쉽게 하기 위해 값 설정
 a.a = 0;
 b.a = 2;
 c.a = 3;

 c = comp_prod(a,b); 
}

호출하는 a함수 스택 메모리영역에 반환값을 위한 임시변수를 만들고

comp_prod 함수에서 그 임시 변수에 값을 써주는 형태로 되어있더군요.

 c = comp_prod(a,b);
==>

 1. 반환을위한 임시 변수 할당.
 2. b 값 push
 3. a 값 push
 4. 반환을 위한 임시변수주소 push
 5. comp_prod call
 6. 변수 c 에 임시변수값 복사

comp comp_prod 함수내에서는

 1. 값 계산
 2. return 을 만나면
    1. 값을 호출한 함수의 임시변수주소에 복사.
    2. ret

C 소스를 만들어 본후에

$ gcc -g -Wall -c test.c -o test.o
$ objdump -S test.o

로 확인해 보세요.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

pynoos의 이미지

아.. 함수를 호출할때는 복사한 구조체에 대한 포인터를 넘길 필요는 없겠군요.

댓글 달기

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