[질문]memset 할 때

zaru의 이미지

typedef struct tagMAN {
    float rate;
    char * name;
    int age;
} MAN;

MAN man;

int main(void)
{
    memset((float *)&man, 0, sizeof(MAN)); // (1)
    memset((char *)&man, 0, sizeof(MAN)); // (2)
    memset((int *)&man, 0, sizeof(MAN));    // (3)

    man.rate = 10.5;
    man.name = "홍길동";
    man.age  = 28;

    printf("man.rate = %f\n", man.rate);
    printf("man.name = %s\n", man.name);
    printf("man.age  = %d\n", man.age);

    return 0;
}

위에서 구조체 사용전에 초기화를 할때
(1), (2), (3) 번 중 어느 것이 맞는지요?
감사합니다.

purewell의 이미지

"man memset" 해보니까...

Quote:
MEMSET(3) Linux Programmer's Manual MEMSET(3)

NAME
memset - fill memory with a constant byte

SYNOPSIS
#include <string.h>

void *memset(void *s, int c, size_t n);

DESCRIPTION
The memset() function fills the first n bytes of the memory area
pointed to by s with the constant byte c.

RETURN VALUE
The memset() function returns a pointer to the memory area s.

CONFORMING TO
SVID 3, BSD 4.3, ISO 9899

SEE ALSO
bzero(3), swab(3)

이렇게 나오네요... :lol:
2번이나 혹은 그냥

memset(&man, 0, sizeof(MAN))

라고 해도 될 듯하네요...

VC6에서는 (char*)를 반드시 붙여야하지만요...
(프로토타입을 그렇게 정의하였음)

_____________________________
언제나 맑고픈 샘이가...
http://purewell.biz

dyaus의 이미지

Quote:

typedef struct tagMAN {
float rate;
char * name;
int age;
} MAN;

MAN man;

int main(void)
{
memset((float *)&man, 0, sizeof(MAN)); // (1)
memset((char *)&man, 0, sizeof(MAN)); // (2)
memset((int *)&man, 0, sizeof(MAN)); // (3)

man.rate = 10.5;
man.name = "홍길동";
man.age = 28;

printf("man.rate = %f\n", man.rate);
printf("man.name = %s\n", man.name);
printf("man.age = %d\n", man.age);

return 0;
}

man 만 확인해 보셔도 될거 같은데요.
void *memset(void *s, int c, size_t n);

memset((void *)&man, 0, sizeof(MAN)); 이렇게 작성하시면 될 거 같습니다.

scobyseo의 이미지

멀 그렇게 복잡하게들 생각하시는지 --;

memset (&mem, 0, sizeof (MEM));

이 가장 좋구요, 나머지 다른 것들도 다 옳긴 합니다.

모든 포인터는 void * 로 알아서 타입 변환이 되니까요...

다른 방법들은 돌아서 포인터 변환하는 거자나요 ^^

서명:
이것은 올리는 글에 첨부될 사인 문구입니다. 제한은 255 글자입니다

B00m의 이미지

엄연히 말하면
memset((void *)&man, 0, sizeof(MAN));
가 옳습니다.

왜냐면 그렇게 정의 되어 있기 때문이죠..

C 같은 경우에는 타입이 안 맞아도 에러를 내지는 않지만 C++ 같은 경우는 타입이 굉장히 중요하게 작동하기 때문에 타입을 확실히 명시해 줘야 합니다.

여기서는 memset 이라는 함수가 단 하나이고 타입이 void* 형이기 때문에 별 문제 없이 컴파일되고 작동하지만 그렇지 않을 경우는 문제가 될 수도 있습니다.

낙엽의 이미지

위에 typedef로 MAN을 사용자 변수형으로 지정하셨으니..

memset((MAN *)&man, 0, sizeof(MAN)); 으로 하셔도 무방할듯 ^^

aero의 이미지

어떤 분들은 포인터로 스트링이나 기타 영역을 지정하고 메모리를 할당한다음
꼭 memset으로 할당받은 영역을 0값으로 clear하고나서 쓰도록 코딩하시는
분들이 있더군요.

그런데 제생각에는 그 이유가 혹시 실수해서 데이터중에 NULL terminator가
빠졌을 경우 에러를 방지하기 위함이 아닌가 싶은데.. 그런 방식으로 해서
프로그래밍상의 오류가 운좋게 넘어갔다고 하면 실제 존재하는 버그를 잡지
못하게 되고 memset이라는 함수를 호출 할때마다 어느정도 클럭도 잡아먹어서
프로그램의 퍼포먼스도 다소 떨어지게 되리라 생각됩니다.

차라리 코딩을 완벽히 해서 memset을 안써도 문제가 없게
만드는게 오히려 낫다고 생각하는데 여러분은 이에 대해 어떻게 생각하시는지요?

최종호의 이미지

몇몇 경우에는 structure를 초기화하는데 그냥 memset 으로 0으로
밀어버리는 경우도 있고 (struct sockaddr_in 등...)
제 경우에는 NULL 안 넣어주는 경우의 에러를 방지하는 것 보다는
(이런 경우는 거의 없다고 보여집니다. 대부분 메모리 영역을 넘어서
데이터가 쓰여질 때 에러가 발생하는데 memset으로 0을 채워주는 경우는
이런것에는 쓸모가 없어지니까요. strncpy() 등 n 시리즈는 도움이
될 수도 있겠지요.)
디버깅할 때 조금 더 편한 것 같습니다.
그냥 가비지로 두면 어떤 값이 변했는지 보기가 좀 어렵더라구요.

오버해드 관련해서는, 전에 한번 매 이벤트 루프마다 time()이 몇번
들어가는 것 같아서 좀 줄여볼까 하다가
1초에 time() 수십만번 부를 수 있는 것 보고 그냥 뒀습니다.
뭐 보통 사양의 보통 서버프로그램이라면
초당 500-2000 정도 이벤트루프가 돌텐데,
매 루프마다 수십, 수백번 불리는 것 아니면 관심있는 영역은 0으로
채울듯 싶습니다.

매크로를 써서 디버깅용과 릴리즈용을 다르게 가져가실 수도 있겠고요.

정재호의 이미지

토를 달자는 건 아니지만
memset(&man, 0, sizeof(MAN)); 이 무난하고 설계 의도에 맞는 사용법이라고 설명됩니다. 첫번째 arg가 void *로 선언된 것은 이 함수를 모든 타입의 포인터에 사용하고자 하는 의도로 memset을 설계했기 때문입니다.

만일 oo 언어로 첫번째 arg의 유형에 의존하여 다른 동작을 해야하는 함수를 설계한다면 마땅히 memset(int *,...) memeset(char *,...) 따로 구현해야 하겠지요. 그런 의도로 설계된 함수라면 memset(void *,...)는 만들지 말아야 할 것 같고요. 오히려 c가 아닌 oo 언어에서 그런 type casting에 의존해서 바인딩이 이루어지도록 한다면 잘못된 설계일듯.

그리고 무엇보다 memset은 c 함수니까 c로 생각하면서 써야 하지 않을까 하는 생각을 :)
이거 써놓고 보니 완전 토단거네요. 죄송스러워라. 그냥 갑자기 oo가 그리워져서 썼습니다. 죄송~~

댓글 달기

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