질문 있습니다..^^;;

어쩌라구의 이미지

안녕하세요..
현직에 들어선지 1달된 신참 인사드립니다..(__);

오늘 회사에서 꾸지람 몇가지를 듣고 질문을 하게되었습니다..
sample-1)
char temp1 = "abcdef";
char temp2[strlen(temp1)];
strcpy(temp2, temp1);

sample-2)
char temp1 = "abcdef";
char temp2[128];
strcpy(temp2, temp1);

위의 sample-1 코드가 제가 짰던 코드 부분 입니다..
사수께서는 sample-2 형태로 하시라고 하는데..
sample1 과 2의 차이점에 대한 자세한 설명 좀 부탁드립니다..;;

neogeo의 이미지

상황에 따라 매우 다르겠군요..

그러나 sample1 은 중대한 문제가 있습니다.

strlen 은 일단 temp1 문자열 자체의 길이를 return 하므로

null 문자가 들어갈 공간이 빠져있어서 문제가 있습니다. ( 즉 나중에 한참 돌리다 보면 temp2 를 찍어보면 null 로 끝나지 않아

심각한 문제가 발생할 수 있습니다. )

적어도 temp2 의 사이즈는 strlen(temp1) + 1 로 해야 할 듯 합니다.

그 이외에 char* 의 size 를 strlen 을 이용해 집어 넣는다는 발상은 혹시 메모리를 아끼시려고 그러시는 특수 상황 + temp1 의 문자열 길이 만큼의 문자 보다 긴 문자가 절대 temp2 에 들어갈 일이 없다는 상황이 100% 확실하다면 sample1 처럼 쓰셔도 좋지만,

만약 문자열 길이가 조금 더 긴게 온다던가 메모리 아끼는거보다 성능이 중요한 app 에선 절대 피해야 할 행동입니다.

일단 temp2 에 strcpy ( temp2 , "gafdgfdgadfgadfgdf" ); 라고만 와도 벌써 buffer overflow 등을 피할 수가 없습니다.

또한 strlen 자체가 overhead 가 있는 연산인데 그것을 저기에 넣어버리면 자체로 128 을 넣은 것 보다 overhead 가 크겠지요.

애초에 128 을 주신것도 128 은 2의 제곱 형태이므로 메모리 할당 , 관리에 효율적이 될 확률이 높습니다. ( padding 등에 유리하기도 하고 )

메모리 단편화를 많이 피하기에도 유리하지요. ( 즉 미리 일정 크기로 할당해서 충분한 사이즈로 잡아두는게 유리하긴 합니다. )

그리고 strlen 은 compile time 에는 리턴값을 알기 힘듭니다. ( 진짜 똑똑한 일부 컴파일러에서도 될지 의문입니다. )

따라서 heap , stack 공간 어디에 temp2 가 위치하게 될지 여부도 갈라집니다. ( 상황에 따라 )

여러가지 이유로 sample2 처럼 사용하라고 사수께서 말씀하셨을 겁니다.

정말 메모리를 아끼려는 의도 + 문자열 길이가 절대 고정이다 라는 상황이 아닌이상 절대 저렇게 쓰면 안됩니다.

Neogeo - Future is Now.

어쩌라구의 이미지

댓글 감사드립니다..^^;
사수께서도 컴파일과 메모리 공간을 언급하시면서 꾸지람 하셨는데..;;
좀더 내공 쌓기에 열중해야겠네요..;;

seank76의 이미지

저는 neogeo 님과 조금 생각이 틀립니다.

만일 temp2가 단지 temp1의 복사본이라면 같은 사이즈로 해주시는게 맞다고 생각합니다.
물론 strlen(temp1) + 1 으로 하셔야죠.

neogeo님의 예제의 정반대 상황이 전 더 불안하네요.
그러니까 temp1이 미리 지정해둔 128보다 더 길다면 바로 오버플로우 뜨겠죠.

꼭 지정된 정수값을 쓰는 경우는 실행속도를 단축시켜야 할때뿐일겁니다.

하지만 기억하셔야될 부분은, neogeo님께서도 언급하셨듯이 strlen()으로 array를 초기화 시키실수는 없읍니다.
제가 알기론 콤파일이 안될텐데, 신기하네요.

char *temp2 = new char[strlen(temp1) + 1];

이렇게 해주세요. (나중에 delete해주시는거 잊지마시고요^^)

nettism의 이미지

부럽습니다..ㅡ.ㅡ

전 책 하나 들고, 오류 생길때마다, 외국 메이커 회사에 메일 띄워서 물어보고, 답변 안오면, 진짜로 생짜로 헤메이곤 했었는데,,무진장 좋은 사수이신가 봅니다..ㅡ.ㅡ

부럽습니다..ㅡ.ㅡ
흑흑..

일신 일일신 우일신


================
일신 일일신 우일신
================

refill의 이미지

뜬금없지만..

strcpy 보다 strncpy를 사용하시는게 어떠실지..

바람과 같이

바람과 같이

only2sea의 이미지

Quote:
하지만 기억하셔야될 부분은, neogeo님께서도 언급하셨듯이 strlen()으로 array를 초기화 시키실수는 없읍니다.
제가 알기론 콤파일이 안될텐데, 신기하네요.

C99부터인가 아마 이런 경우에 동적으로 메모리 할당을 해 줄겁니다. 이 경우에는 상수 문자열이므로 윗분께서 말씀하신대로 컴파일러가 심하게 똑똑하면 정적으로 할당하는 것도 가능하지요.

이제는 서명에 무엇을 써야하는지 생각해보자.

alwaysrainy의 이미지

컴파일러에 따라서 불안불안 할 듯 한데요...
저런 경우 저는 보통 아래와 같이 코딩합니다.

int len;
char *temp1 = "abcdef";
char *temp2;
 
len = strlen(temp1);
temp2 = (char *)malloc(sizeof(char)*(len+1));
strncpy(temp2, temp1, len);
temp2[len] = '\0';

세계는 넓고, 할일은 많다.

---------------------------------------
세계는 넓고, 할일은 많다.

익명사용자의 이미지

같은 용도로 strdup(strndup) 한방에 끝낼 수 있습니다.

NUL terminated 보장은 안 됩니다.

BSD 계열은 strlcpy 도 있습니다. 이 함수는 항상 NUL terminated

보장됩니다. 할당해주지는 않고 strncpy 대용입니다.

coremaker의 이미지


원래 예를 들어.. 예전엔 안된다고 생각했던 코드가 바로 요런게 있겠죠

 
        void strex(int length) {
             char str[length];
        }
 

실제로 저런 경우 예전 ANSI C 에서는 malloc 처리를 해줘야했습니다만..
최근에 가능해 졌지요.. (뭐 이게 당연한거 아니야 라고 생각하시는 분들도 계시겠지만.. )

그리고 뭐 이런저런 기술적인 문제를 접고..
코딩 스타일을 생각해 보자면.. 라인 수를 줄이겠다고..
한라인에 많은 코드를 삽입하는 것은 여러모로 안좋은 점도 있습니다..
( 물론 가끔 간결하고 강력할 수도 있습니다만.. )

더 Debugging 하거나.. 할 때 한라인에 여러 요소가 겹쳐 있다면 상당히 보기가 힘든 경우가
있기도 합니다..

댓글 달기

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