[완료]배열 값이 안 넘어 옵니다.

coathanger의 이미지

안녕하세요..
혼자 해결이 안되어 질문 올립니다...

아래 소스는 프로그램 일부 중 문제가 있는 부분만 간추려 작성하였습니다.

일단 현재 개발 환경에서 아래를 컴파일하여 실행하면..
의도한 10, 20이라는 값이 main함수에서 출력되지 않습니다.

이상하게도 function1 함수에 주석이 걸린 부분을 주석 해제하여 그 값이 출력되면 main함수에서
제대로 값이 출력되고요. 왜 이런 현상이 있는지 알 수 없어 질문 드립니다..
코드가 잘 못 된건가요.. 아니면 오래된 컴파일러에서 이러한 경우가 생길 수 있는건지요..

unsigned char* function1(void)
{
unsigned char ucField[2];

ucField[0] = 10;
ucField[1] = 20;

//printf("%d, %d\n", ucField[0], ucField[1]);

return ucField;
}

int main(void)
{

unsigned char *addr;

addr = function1();

printf("%d, %d\n", addr[0], addr[1]);
}

김일목의 이미지

unsigned char* function1(void)
{
unsigned char ucField[2];

ucField[0] = 10;
ucField[1] = 20;

//printf("%d, %d\n", ucField[0], ucField[1]);

return ucField;
}

이런 코드를 만드시면 절대절대 안됩니다.

function1 에서 선언하신 unsigned char ucField[2]는 로컬 변수 입니다.
당연히 해당 함수가 끝남과 동시에 소멸해 버립니다.
함수내부의 comment를 해제해서 실행이 되는것은 순전히 우연입니다.
그 위치에 저장이 우연히 되어있고, 아직 메모리가 다른 것에
침범을 당하지 않았으므로, 프로그램은 그냥 실행을 해버리죠..
이 코드는 실행되도 나중에 큰 문제를 수반하게 될 겁니다.

만약 이렇게 사용하고 싶으시다면 다음과 같이 바꾸셔야 합니다.

unsigned char* function1(void)
{
unsigned char ucField = (unsigned char) malloc(sizeof(unsigned char)*2);

ucField[0] = 10;
ucField[1] = 20;

//printf("%d, %d\n", ucField[0], ucField[1]);

return ucField;
}

int main(void)
{

unsigned char *addr;

addr = function1();

printf("%d, %d\n", addr[0], addr[1]);

delete addr;
}

cppig1995의 이미지

malloc으로 할당하고 delete로 해제하거나, new로 할당하고 free로 해제하는 것은,
new로 할당하고 delete[]로 해제하거나, new[]로 할당하고 delete로 해제하는 것과 같이
정의되지 않은 동작(undefined behavior)을 일으킨다고 알고 있습니다.
------------------------------------------------------
In simplexitate est opportunitas. --cppig1995
[낡배밀] 낡은 리눅스 배포판을 밀어내야 한다고 생각합니다.

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

coathanger의 이미지


헉.. 제가 정말 잘못 알고 있었나 보내요...
보통 저런식으로 데이터를 반환했고.. 에러 없이 사용을 했었거든요.. 이처럼.. 데이터가 출력 안되는 건 이번이 처음입니다..
그럼 여태 것 잘못 작성 한 것이군요 -_-;

그그럼.. 지금 처럼 배열일 경우만 이렇게 하는 것이 아니고.. 변수 내의 모든 로컬 변수가 다 적용 되는 건가요?

그렇다면 일반적으로 특정 함수 내의 지역 변수, 배열, 주소 값을 어떤 방식으로 넘기나요?
답변 해주신 것 처럼 동적 메모리를 할당 하여야 하나요? 전역변수를 선언해야 하나요?

예를 알고 싶네요.. 현재 보다 큰 프로그램을 작성 중인데.. 이 처럼 실수를 하면.. 나중에 큰 문제를 야기 시킬 것이 분명 하겠군요..

seoleda의 이미지

어떤 코드를 보니깐

static unsigned char ucField[2];

이런식으로 리턴할 변수를 static으로 지정하더군요.
static을 사용하면 프로그램이 끝나기 전까지 메모리에 살아 있기 때문에 문제 없다고 알고 있습니다.

bootmeta의 이미지

지역 변수의 int, char,float같은 데이타는 당연히 함수내에 할당된 stack이 사라지더라도 이미 값 자체는 복사되어 return되었으므로 문제가 없습니다. 당연히 그렇게 쓰는게 맞습니다.

그러나 지역변수로 사용된 배열은 함수를 빠져나가는 경우 함수가 사용한 stack이 해제되면서 return으로 넘겨진 배열이름(실제로는 배열의 첫 주소)은 더이상 stack내의 배열에 접근할 수 없게 됩니다.
함수 외부에서 배열을 잡아놓고 배열 주소를 넘겨 주거나, 동적 메모리를 할당하거나 전역 변수를 쓰거나 또는 함수 내부에서 static 변수로 선언하면 됩니다.
방법들은 장단점이 있으니 상황에 맞춰 쓰면 됩니다.
멀티쓰레딩이나 동적라이브러리, c,c++혼용 코드냐등의 다양한 요인이 있어 한마디로 하기가 힘들군요.
c, c++에 관련된 주의점이나 버그 회피 코드 작성에 관한 책이나 문서들을 참조해보는 것도 도움이 될 듯 하군요.

helloneo의 이미지

흔히 말하는 call by reference.. 주소값을 넘겨주는 방법이 있습니다..

int function1(unsigned char* ucField)
{

ucField[0] = 10;
ucField[1] = 20;

//printf("%d, %d\n", ucField[0], ucField[1]);

return 0;
}

int main(void)
{

unsigned char addr[2];

function1(addr);

printf("%d, %d\n", addr[0], addr[1]);
}

근데 코드 이쁘게나오게하는방법 뭔가요..?
코드 태그같은거 있나요..?

WHAT'S UP

sephiron의 이미지

"\[code\]" "\[/code\]" 가 있긴 한데 색깔은 PHP 소스만 입혀집니다.

댓글 창 밑에 있는 "입력 형식"을 눌러보세요.

magingax의 이미지

...

LISP 사용자모임
http://cafe.naver.com/lisper
방송기술 개발업체
http://playhouseinc.co.kr

doodoo의 이미지

<code>  로 감싸 주십시요...
잘 되는것 같군요..

int function1(unsigned char* ucField)
{
 
  ucField[0] = 10;
  ucField[1] = 20;
 
  //printf("%d, %d\n", ucField[0], ucField[1]);
 
  return 0;
}
 
int main(void)
{
 
  unsigned char addr[2];
 
  function1(addr);
 
  printf("%d, %d\n", addr[0], addr[1]);
}
magingax의 이미지

(defun function1 ()
   '(10 20))

LISP 사용자모임
http://cafe.naver.com/lisper
방송기술 개발업체
http://playhouseinc.co.kr

Fe.head의 이미지

int function1(unsigned char* ucField, const int size)
...
 
function1(addr, sizeof(addr));

형태로 해야 될듯..

-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.