strcpy()함수 사용법에 대해서..

toold의 이미지

class Element{
public:
	char *lastName;
	char *firstName;
};

void main()
{
	Element a, b, c, d, e, f;

	strcpy(a.firstName, "test");
	strcpy(a.lastName, "test2");
}

코드가 대충 위와 같은데요..
컴파일시 에러는 없는데..
실행하면 왜 멈추어버리죠..?..
strcpy()를 잘못 사용한건가요..?..
맞는거 같은데.. :wink:
monpetit의 이미지

strcpy()를 사용하시려면 포인터가 아니라 문자배열로 정의하셔야 합니다.
차라리 std::string을 사용하시는 게 어떨까요...

toold의 이미지

감사합니다..
죄송한데..
std::string 에 대해서 간단한 예제 좀 들어주실 수 있을까요..
처음 들어보는 거라서요..^^;;

맹고이의 이미지

#include <string>

class Element {
        public:
                std::string lastName;
                std::string firstName;
};

int main() {
        Element a;

        a.lastName = "foo";
        a.firstName = "bar";
}

이렇게 하면 될 듯...
그리고 string class는 c++ 기초책에도 잘 나와있을 겁니다... 8)
nohmad의 이미지

제가 생각하는 원인은 이렇습니다.

우선 다음 코드는 GCC에서는 잘 작동합니다.

int main(void)
{
    char *inner;
    strcpy(inner, "inner");
    printf("%s", inner);
}

아마도 함수 안에서 선언된 문자 포인터(char *)는 자동변수가 되어 스택 안에서 적당한 초기화가 이루어지면서 strcpy가 요구하는 destination address를 만족시키는 것 같습니다. 알고 계시겠지만 전역변수의 경우에는 malloc 없이 사용하면 segmentation fault가 어흥하고 달려들지요. :)

char *outer;
int main(void)
{
    //outer = (char *) malloc(sizeof(char)*10);
    strcpy(outer, "outer");
    printf("%s", outer);
}

마찬가지로 Element내에 선언된 문자 포인터의 경우 초기화되지 않았기 때문에 malloc 이전에는 사용할 수 없을 것이라고 생각했는데, 놀랍게도 C의 구조체 패딩처럼 class도 비슷한 초기화가 이루어지는지 3바이트까지 strcpy가 가능하네요. 아래 코드는 잘 작동합니다.

#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

class Element
{
public:
    char *p;
    char *q;
};

int main(void)
{
    Element a;
    strcpy(a.p, "123");
    strcpy(a.q, "456");
    cout << a.p << endl;
    cout << a.q << endl;
}

방금 발견한 놀라운 사실. class의 멤버가 하나일 때, 또는 마지막 멤버의 경우는 제한없이 마구 사용할 수 있군요. 위 코드에서 q에 더 많은 문자열을 넣어도 잘 작동하네요.

ㅡ,.ㅡ;;의 이미지

nohmad wrote:
제가 생각하는 원인은 이렇습니다.

우선 다음 코드는 GCC에서는 잘 작동합니다.

int main(void)
{
    char *inner;
    strcpy(inner, "inner");
    printf("%s", inner);
}

아마도 함수 안에서 선언된 문자 포인터(char *)는 자동변수가 되어 스택 안에서 적당한 초기화가 이루어지면서 strcpy가 요구하는 destination address를 만족시키는 것 같습니다. 알고 계시겠지만 전역변수의 경우에는 malloc 없이 사용하면 segmentation fault가 어흥하고 달려들지요. :)

char *outer;
int main(void)
{
    //outer = (char *) malloc(sizeof(char)*10);
    strcpy(outer, "outer");
    printf("%s", outer);
}

마찬가지로 Element내에 선언된 문자 포인터의 경우 초기화되지 않았기 때문에 malloc 이전에는 사용할 수 없을 것이라고 생각했는데, 놀랍게도 C의 구조체 패딩처럼 class도 비슷한 초기화가 이루어지는지 3바이트까지 strcpy가 가능하네요. 아래 코드는 잘 작동합니다.

#include <iostream>
#include <string.h>
#include <stdlib.h>

using namespace std;

class Element
{
public:
    char *p;
    char *q;
};

int main(void)
{
    Element a;
    strcpy(a.p, "123");
    strcpy(a.q, "456");
    cout << a.p << endl;
    cout << a.q << endl;
}

방금 발견한 놀라운 사실. class의 멤버가 하나일 때, 또는 마지막 멤버의 경우는 제한없이 마구 사용할 수 있군요. 위 코드에서 q에 더 많은 문자열을 넣어도 잘 작동하네요.

그런게 아닙니다.
오토변수로 선언했다하여 실제메모리가 할당되는것은 아닙니다.
전역변수로 하면 바로 오류가 나는이유는 전역변수로 잡을때 NULL 로 초기화 되기때문에 바로 오류가 나는것이고
함수내부의 오토변수로 선언되었을때는 오히려 초기화가 되지 않아 쓰레기 값을 가지게 되고.. 따라서 아무 주소번지나 가리키게 되는겁니다.
다행이 운이 좋아 그메모리를 써도 별탈 없을경우에는 오류가 안나다가 재수 없으면 뻗어버립니다..
둘다 무저건 실제메모리를 할당해줘야합니다.


----------------------------------------------------------------------------

nohmad의 이미지

ㅡ,.ㅡ님 감사합니다. 제가 착각한 것 같군요.

위에서 제가 얘기한 것들은 잊어주시기 바랍니다. gcc 버전의 문제 같습니다. 같은 버전인데도 다른 머신에서 해보니 class의 char * 멤버에 malloc 없이 더 긴 문자열을 strcpy 할 수 있네요. -_-; 역시 undefined behavior인 것 같습니다.

댓글 달기

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