메시지 큐를 코딩중입니다. 솔라리스10 C++ 도와주세요

idrukawa의 이미지

솔라리스 10에서 c++ 코딩 중 입니다.

간단한 메시지 큐를 만들어서 테스트 중인데요.
함수인자로 결과값을 받아오려고 합니다.
함수내부에서 출력해보면 정상적으로 출력이 되는데
main에서 결과값을 받아온 인자를 출력해보면 엉뚱한 값이 출력됩니다.
포인터를 사용해서 제대로 한 것 같은데
확인 한번만 해주세요. 다음은 코드 전문과 결과 출력화면입니다.
컴파일 해보려면 -lpthread 옵션을 주어야 합니다.

결과화면
*** Init message queue.
msgq->count = 0

*** Insert data
insert_data = 0
insert_data = 1
insert_data = 2
insert_data = 3
insert_data = 4
insert_data = 5
insert_data = 6
insert_data = 7
insert_data = 8
insert_data = 9
msgq->count = 10

*** Get data // error: 모법 출력 0 1 2 ... 9
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
get_data = 0
msgq->count = 0

MyMsgQ.h

#ifndef _MY_MSG_Q_H_
#define _MY_MSG_Q_H_
 
typedef struct element_s{
    struct element_s *prev;
    struct element_s *next;
    void *data;
}element_t;
 
 
typedef struct msgq_s{
    long count;         // existed element count 
    element_t *head;    // entrance
    element_t *tail;    // exit
}msgq_t;
 
 
class MyMsgQ
{
    private:
    protected:
    public:
        MyMsgQ::MyMsgQ();
        MyMsgQ::~MyMsgQ();
        element_t MyMsgQ::create_element(void *new_data);
        int MyMsgQ::init_msgq(msgq_t *msgq);
        int MyMsgQ::insert_head(msgq_t *msgq, element_t *new_element);
        int MyMsgQ::get_tail(msgq_t *msgq, void *load_data);
};
 
#endif

MyMsgQ.cpp

#include <iostream>
 
#include "MyMsgQ.h"
 
pthread_mutex_t msgq_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 
MyMsgQ::MyMsgQ()
{
 
}
 
 
MyMsgQ::~MyMsgQ()
{
 
}
 
 
element_t MyMsgQ::create_element(void *new_data)
{
    element_t new_element;
 
    new_element.prev = NULL;
    new_element.next = NULL;
    new_element.data = new_data;
 
    return new_element;
}
 
 
int MyMsgQ::init_msgq(msgq_t *msgq)
{
    pthread_mutex_lock(&msgq_mutex);
 
    msgq->count = 0;
    msgq->head = NULL;
    msgq->tail = NULL;
 
    pthread_mutex_unlock(&msgq_mutex);
 
    return msgq->count;
}
 
 
int MyMsgQ::insert_head(msgq_t *msgq, element_t *new_element)
{
    pthread_mutex_lock(&msgq_mutex);
 
    if( msgq->count == 0 ){
        msgq->head = new_element;
        msgq->tail = new_element;
        msgq->count++;
    }
    else if( msgq->count > 0 ){
        msgq->head->prev = new_element;
        new_element->next = msgq->head;
        msgq->head = new_element;
        msgq->count++;
    }
 
    pthread_mutex_unlock(&msgq_mutex);
 
    return msgq->count;
}
 
 
int MyMsgQ::get_tail(msgq_t *msgq, void *load_data)    // load_data가 결과를 저장할 인수입니다.
{
    pthread_mutex_lock(&msgq_mutex);
 
    if( msgq->count == 0 ){
        pthread_mutex_unlock(&msgq_mutex);
 
        return -1;  // Return Empty
    }
    else if( msgq->count == 1 ){
        load_data = msgq->tail->data;
        free(msgq->head);
        msgq->head = NULL;
        msgq->tail = NULL;
        msgq->count--;
    }
    else if( msgq->count > 1 ){
        load_data = msgq->tail->data;
//      printf("msgq->tail->data = %d\n", (int *)msgq->tail->data);    // 함수 내부에서 출력해보면 정상적으로 출력이 됩니다.
//      printf("load_data = %d\n", (int *)load_data);    // 함수 내부에서 출력해보면 정상적으로 출력이 됩니다.
 
        msgq->tail = msgq->tail->prev;
        free(msgq->tail->next);
        msgq->tail->next = NULL;
        msgq->count--;
    }
 
    pthread_mutex_unlock(&msgq_mutex);
 
    return msgq->count;
}

use_my_msgq.cpp

#include <iostream>
 
#include "MyMsgQ.h"
 
#define MAX_ELEMENT 10
 
 
int main()
{
    MyMsgQ *my_msgq_i = new MyMsgQ();
 
    /* Init message queue. */
    printf("*** Init message queue.\n");
 
    msgq_t msgq;
    my_msgq_i->init_msgq(&msgq);
 
    printf("msgq->count = %d\n\n", msgq.count);
 
    /* Insert data */
    printf("*** Insert data\n");
 
    int i;
    element_t element[MAX_ELEMENT];
 
    for(i = 0 ; i < MAX_ELEMENT ; i++){
        element[i] = my_msgq_i->create_element((void *)i);
        my_msgq_i->insert_head(&msgq, &element[i]);
        printf("insert_data = %d\n", (int *)msgq.head->data);
    }
 
    printf("msgq->count = %d\n\n", msgq.count);
 
    /* Get data */
    printf("*** Get data\n");
 
    void *load_data = NULL;
    element_t *tmp_element = msgq.head;
    for(i = 0 ; i < MAX_ELEMENT ; i++){
        my_msgq_i->get_tail(&msgq, load_data);    // error: 문제가 되는 부분입니다.  죄다 0으로 찍히네요 ㅠ  값을 전달 받지 못하는것 같습니다.
        printf("get_data = %d\n", (int *)load_data);
    }
    printf("msgq->count = %d\n\n", msgq.count);
 
    return 0;
}

idrukawa의 이미지

여기에 소스 코드를 올리니 엉망이되네요 ㅠ
찾기 편하도록 문제가 되는 부분을 // error: ~~~ 로 적어놨습니다.
잘 부탁드립니다.

Fe.head의 이미지

코드 양끝으로 [ code ] code [ /code ]를 써보세요.

get_tail(msgq_t *msgq, void *load_data) 이부분이 잘못된것 같아보입니다.

void *load_data 을 void ** load_data 으로 해보시거나
void *& load_data 로 해보심이.

int MyMsgQ::get_tail(msgq_t *msgq, void *&load_data)

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

idrukawa의 이미지

 
좋은 정보 감사합니다 ㅎㅎ

함수정의를
int MyMsgQ::get_tail(msgq_t *msgq, void **load_data)
위와 같이 해주니까 되네요..
물론 사용하는 부분도 수정했구요 ㅎ

그냥 포인터만 써도 될것 같았는데
이중포인터를 써야하는 이유를 알 수 있을까요?
대충 이렇겠구나 감은 오는데 다른 분께 설명을 들으면 확실할 것 같아서요.
답변 감사합니다.

근본적인 것에 대한 논의가 재미있는것 같아요 ㅎ

february28의 이미지

더럽죠..
그리고, int load_data;라고 하시고 &load_data로 넘겨주시는게 옳을듯..

--------------------------------------------------------------------------------
open source, open teaching, 천기누설이 꿈~ 은 개뿔...
--------------------------------------------------------------------------------

idrukawa의 이미지

아~ 데이터형을 저렇게 void *로 잡은것은
어떤 데이터든 넘겨줄 수 있도록 하기 위함 입니다.

답변 감사합니다 ^^

Fe.head의 이미지

void swap( int a, int b)
{
  int tmp = a;
  a = b;
  b = tmp;
}

위의 코드를 아무리 호출해봐야 값이 바뀌지 않습니다.

값으로 전달했기 때문이죠.

포인터도 마찬가지로 값으로 전달됩니다.

int main()
{
  int i = 0;          // i 주소가 100번지라고 가정
  get(&i);            // 100 값을 넘김(i 주소)
  printf("%d\n", i);
  return 0;
}
 
void get(int * pI)
{
  // pI 에는 값 100이 있음
  pI = 0;   // 100인 pI값을 0으로 바꿈.
 
  // *pI = 0;   --> 100번지에 있는 값을 0으로 바꿈.
}

설명을 잘못하겠네요 ㅎㅎ

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