[C++] void * 형의 포인트 사용 에러.

antz의 이미지

안녕하세요. :-)

C에서는 컴파일이 잘되던것이
C++에 오니 에러를 내는군요.

이유와 방법을 알려 주시면 감사하겠습니다.

...
void *pIndex;
IndexDouble *tmpIndex;
IndexDouble target;
...
while(1)
{
    ...
    memcpy(((void *)(pIndex) + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble)); // 485 줄
    nUni++;
    ...
    tmpIndex = (IndexDouble *)(pIndex + (i*sizeof(IndexDouble))); // 503 줄
    ...
}

Quote:
dhjang@linuxbox:~/se300/src$ make
gcc -DMYSQL_SERVER \
-DHAVE_CONFIG_H -DUSE_ALARM_THREAD \
-O3 -DDBUG_OFF -I'/usr/include/mysql' -I../include \
-shared -o lets114.so lets114.cc -L'/usr/lib' -lmysqlclient -lz -lcrypt -lnsl -lm
lets114.cc: In function `char* Process2(int, const char*, int)':
lets114.cc:485: error: pointer of type `void *' used in arithmetic
lets114.cc:503: error: pointer of type `void *' used in arithmetic
make: *** [lets114.so] Error 1
dhjang@linuxbox:~/se300/src$ vim lets114.cc
서지훈의 이미지

IndexDouble은 뭡니까?
그리고 485라인 이전에 pIndex에 포인터 지정 해 주셨는지?

이런 경우는 저도 처음이라 여러가지 가설만...

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

new5244의 이미지

void 포인터형 변수에 arithmetic 연산을 수행해서 발생하는 문제네요.
왜 그런지는 c++ 을 책을 보면 금방 아실수 있습니다.

pIndex 를 arithmetic 연산이 가능한 type 으로 먼저 casting 한 후에 사용하면 됩니다.

memcpy(((void *)(pIndex) + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble));

==>

memcpy( (void *) ( ( type casting )pIndex + nUni * sizeof(IndexDouble) ), &target, sizeof(IndexDouble));

int 도 되고 char * 도 되고 .... 해당 variable 값에 영향을 주지 않도록 적절한 type 을 선택하세요.

from saibi

hanseok의 이미지

new5244 wrote:
void 포인터형 변수에 arithmetic 연산을 수행해서 발생하는 문제네요.
왜 그런지는 c++ 을 책을 보면 금방 아실수 있습니다.

음..~~ ^^;

(void*)point + X  이렇게 하면. X 의 값을 어떻게 처리하나요..?  (이것이 에러의 원인)

(int*)point + X  ==> point 주소값 + sizeof(int) * X  <== 맞나요? (이렇게 해줘야 한다는 말씀이죠)

그렇다면..
C에서 에러가 없다면 point + X 에서 X 의 값은 그냥 byte 로 생각해서 값을 증가시키나요? (궁금해지네요. )

잠이 들어야지만 꿈을 꿀수 있는것인가?
우리는 항상 꿈을 쫓아 가며 살아가는 사람들..

antz의 이미지

서지훈 wrote:
IndexDouble은 뭡니까?

IndexDouble은 typedef 로 선언한 structure 변수 입니다.

antz의 이미지

고맙습니다.

도움이 되었습니다.

while(1)
{
    ...
    memcpy(((IndexDouble*)pIndex + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble));
    nUni++;
    ...
    tmpIndex = ((IndexDouble *)pIndex + (i*sizeof(IndexDouble)));
    ...
}

이렇게 하니 에러가 안나는 군요. :-)

에러의 원인은 찾아 봐야 겠네요.

제가 제대로 알지못하고 막 사용하는 경향이 있어서...

고쳐야하는데 잘 안되는군요.

답변 감사드립니다.

new5244 wrote:
void 포인터형 변수에 arithmetic 연산을 수행해서 발생하는 문제네요.
왜 그런지는 c++ 을 책을 보면 금방 아실수 있습니다.

pIndex 를 arithmetic 연산이 가능한 type 으로 먼저 casting 한 후에 사용하면 됩니다.

memcpy(((void *)(pIndex) + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble));

==>

memcpy( (void *) ( ( type casting )pIndex + nUni * sizeof(IndexDouble) ), &target, sizeof(IndexDouble));

int 도 되고 char * 도 되고 .... 해당 variable 값에 영향을 주지 않도록 적절한 type 을 선택하세요.

최종호의 이미지

mollla wrote:
고맙습니다.

도움이 되었습니다.

while(1)
{
    ...
    memcpy(((IndexDouble*)pIndex + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble));
    nUni++;
    ...
    tmpIndex = ((IndexDouble *)pIndex + (i*sizeof(IndexDouble)));
    ...
}

이렇게 하니 에러가 안나는 군요. :-)

에러의 원인은 찾아 봐야 겠네요.

제가 제대로 알지못하고 막 사용하는 경향이 있어서...

고쳐야하는데 잘 안되는군요.

답변 감사드립니다.

원하시는 것이 어떤 것인지 몰라서 확실히 말씀드릴 수는 없지만,
index[nUni] = target 을 원하신 것이라면

memcpy(((IndexDouble*)pIndex + nUni, &target, sizeof(IndexDouble));

이 원하는 것을 수행하는 코드일 것입니다.

지금 쓰신 코드는 index[nUni * sizeof(IndexDouble)] = target 입니다.

target이 strucut 라면 포인터를 넘기시거나 reference 를 넘기시는게 일반적인 방법으로 생각됩니다. :)
참고로, struct 도 그대로 assign하실 수 있습니다.

ssehoony의 이미지

void* 에 대한 산술연산은 C나 C++ 이나 역시 워닝이 뜹니다.
unsigned int 로 타입캐스팅을 해서 계산 후에 다시 결과를 void* 로 변경하셔도 되지만 그게 귀찮다면 void* 사용하는 곳의 모조리 char* 로 사용하시면 생각하시는데로 결과를 얻으실 수 있을겁니다.

antz의 이미지

답변 주신 모든 분께 감사드립니다.

devilhero wrote:
void* 에 대한 산술연산은 C나 C++ 이나 역시 워닝이 뜹니다.
unsigned int 로 타입캐스팅을 해서 계산 후에 다시 결과를 void* 로 변경하셔도 되지만 그게 귀찮다면 void* 사용하는 곳의 모조리 char* 로 사용하시면 생각하시는데로 결과를 얻으실 수 있을겁니다.

위에 되었다고 했었는데, 컴파일은 에러없이 되어도
실행에서 "segmentation fault" 가 나더군요.

char *를 사용하니 에러가 없이 잘 실행됩니다.

감사합니다.

    char *pIndex;
    IndexDouble *tmpIndex;
    ...
    pIndex=(char *)malloc((nRight-nLeft)*sizeof(IndexDouble));
    memset(pIndex, 0x00, (nRight-nLeft)*sizeof(IndexDouble));
    ...

    while(1)
    {
            ...
            memcpy((pIndex + nUni * sizeof(IndexDouble)), &target, sizeof(IndexDouble));
            ...
            tmpIndex = (IndexDouble *)(pIndex + (i*sizeof(IndexDouble)));
            ...
     }
freedom의 이미지

저도 C로 예제를 만들엇 그대로 C++ 로 옮겼는데 같은 문제가 있었습니다.
여기와서 제대로 알고 갑니다.

댓글 달기

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