구조체 함수멤버 사용에 관해서...

kernelbomb의 이미지

간단하게 class를 흉내낼려고 따라하고 있는데 세그먼트 폴트가 나네요.

원래 함수에는 init란게 없어서 name 멤버를 초기화 하지 않아 에러가

나는것 같아 init 함수를 넣어주고 초기화 시켰는데도 세그먼트 폴트가

납니다. 왜이러는지 정말 헷갈리네요.

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

struct  data {
        /* 멤버변수 선언 */
        int             id;
        char    *name;

        /* 멤버함수 선언 */
        void    (*init)(struct data *pData);
        void    (*set_name)(struct data *pData, char *newname);
        char    (*get_name)(struct data *pData);
        void    (*clear)(struct data *pData);
};

void init(struct data *pData)
{
        pData->id = 0;
        pData->name = 0l;

        pData->init = NULL;
        pData->set_name = NULL;
        pData->get_name = NULL;
        pData->clear = NULL;
}

void set_name(struct data *pData, char *newname)
{
        if (pData->name)
        {
                if (strlen(pData->name) < strlen(newname))
                {
                        free(pData->name);
                        pData->name = malloc(sizeof(char) * strlen(newname) + 1);
                }
        }
        else
        {
                pData->name = malloc(sizeof(char) * strlen(newname) + 1);
        }
        strcpy(pData->name, newname);
}

char *get_name(struct data *pData)
{
        if (pData->name)
                return pData->name;
        else
                return NULL;
}

void clear(struct data *pData)
{
        pData->id = 0;
        if (pData->name)
        {
                free(pData->name);
                pData->name = NULL;
        }

        pData->get_name = NULL;
        pData->set_name = NULL;
        pData->clear = NULL;
}

int main(void)
{
        struct  data aData;

        /* 구조체 함수포인터에 각 함수의 주소를 대입한다. */
        aData.init = init;
        aData.get_name = get_name;
        aData.set_name = set_name;
        aData.clear = clear;

        aData.init(&aData);
        aData.id = 100;
        printf("aData.id = %d\n", aData.id);

        aData.set_name(&aData, "test");
        printf("aData.name = %s\n", aData.get_name(&aData));

        aData.clear(&aData);

        return 0;
}
cdpark의 이미지

aData.init(&aData) 를 호출하고 난 후에 aData.set_name()을 호출하는군요. 어떤 사태가 벌어질까요? :(

덤으로 pData->name 의 초기값을 0l 이 아닌 NULL로 하는게 읽기 편하지 않을까요?

불량청년의 이미지

문자열을 리턴해 줘야 하는데 잘 못 선언했군요.

char (*get_name)(struct data *pData);

이것을

char *(*get_name)(struct data *pData);

으로 바꿔야 합니다. 또한 init()에서는

void init(struct data *pData)
{
     pData->id = 0;
     pData->name = NULL;

     pData->init = NULL;
     pData->get_name = NULL;
     pData->set_name = NULL;
     pData->clear = NULL;
}

로 바꿔야 하고 main()에서의 init 호출은 맨 위에서 해야합니다.

H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!

댓글 달기

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