배열과 포인터 질문입니다.

balgarac1의 이미지

void * handle_clnt(void * arg)
{
	int clnt_sock = *((int *)arg);
	int retValue;
	char chMsgBuf[BUFSIZ];
	UB2 ubMsgType;
	char pbuf[2048];
 
	while(true)
	{
		retValue = CNetworkRecvPacket(clnt_sock, pbuf, &ubMsgType);
 
		// ????
		if(retValue == PROGRAM_EXIT)
			continue;
 
		MsgService(ubMsgType, (char *)pbuf, clnt_sock);
	}
}

char 배열을 CNetworkRecvPacket 함수의 인자로 보내고

int CNetworkRecvPacket(int cSock, char * m_pBuf, UB2 * msgType)
{
 
	int recvCnt = 0;
	int msgBytePos = 0;
	int recvPacketCnt = 0;
 
	// cout << "CNetoworkRecvPack... " << endl;
	// m_pBuf 메모리 공간 0으로 초기화
	bzero(m_pBuf, 0);
 
	while(true)
	{
		// 2바이트만 받는다
		recvCnt = recv(cSock, m_pBuf + msgBytePos, sizeof(UB2), 0);
		// 2바이트 이상 받으면 루프 탈출
		if(recvCnt >= sizeof(UB2))
		{
			msgBytePos = recvCnt;
			break;
		}
 
		msgBytePos += recvCnt;
 
		// EOF 프로그램 종료
		if(recvCnt == 0)
			return 0;
 
		// 실패 시 다시 수신한다
		if(recvCnt == -1)
		{
			// cout <<"CNetworkRecvPacket Recv Error" << endl;
			// 클라이언트 비정상 종료시 스레드 자료구조에서 삭제 하는 함수 호출
		}
	}
 
	// 메세지 타입 식별 위해 2바이트 복사
	memcpy(msgType, m_pBuf, sizeof(UB2));
	cout << "DBServer msgType : " << *msgType << endl;
 
	// 로그인 요청
	if(*msgType == AUTH_REQ_MSG) // 1
	{
		recvPacketCnt = sizeof(dgt_auth_req_msg) - msgBytePos;
		cout << "AUTH_REQ_MSG:" << recvPacketCnt << endl;
	}
	else if(*msgType == SQL_REQ_MSG) // 3
	{
		recvPacketCnt = sizeof(dgt_sql_req_msg) - msgBytePos; // SQL 요청
		cout << "SQL_REQ_MSG:" << recvPacketCnt << endl;
	}
	else if(*msgType == CLOSE_REQ_MSG) // 5
	{
		recvPacketCnt = sizeof(dgt_close_req_msg) - msgBytePos; // 종료 요청
		cout << "CLOSE_REQ_MSG" << endl;
	}
 
	int remainPct = 0;
 
	// 남은 구조체 길이 만큼 수신한다
	while(msgBytePos < recvPacketCnt)
	{
		recvCnt = recv(cSock, m_pBuf + msgBytePos, recvPacketCnt - remainPct, 0);
		if(recvCnt == -1)
			return 0;
		if(recvCnt == 0)
			break;
		msgBytePos += recvCnt;
		remainPct += recvCnt;
 
		cout << "msgBytePos ::: " << msgBytePos << endl;
	}
	m_pBuf[msgBytePos] = 0;
 
	cout <<"m_pBuf size:" << strlen(m_pBuf) << endl;
	return *msgType;
}

이 함수에서 포인터로 받습니다.
cout <<"m_pBuf size:" << strlen(m_pBuf) << endl; <- 이 문장에서 길이가 1로 나오는데

msgBytePos 의 크기는 134로 잘 수신되고 있습니다.

왜 m_pBuf 길이가 1로 나오나요... ㅠ

balgarac1의 이미지

아... 모르겠네요..

bushi의 이미지

strlen(m_pBuf) 는 m_pBuf 주소에 있는 byte 값부터 시작해서 맨 첫번째로 0x00 이 나오기 직전까지의 byte 갯수를 돌려줍니다.

integer 2 라는 숫자는 little endian 기계의 메모리에 0x02 0x00 0x00 0x00 의 byte 배열로 저장되어 있습니다.

balgarac1의 이미지

답글 감사합니다

shint의 이미지

사용하신 방법은 사용하기 어렵습니다.
char buf[100];
char * pBuf = buf;
int size = _msize(pBuf);
이 경우. size 는 -1 이 나오고 있습니다.

--------------------------------------
strlen()은 문자열에 갯수를 얻습니다.
_msize()는 malloc()으로 할당된 갯수를 얻습니다.
sizeof()는 변수에 크기를 얻습니다.

void bzero(void *s, size_t n);
http://www.joinc.co.kr/modules/moniwiki/wiki.php/man/3/bzero

bzero() 대신

char buf[1024];
int size = sizeof(buf);
memset(buf, '\0', size); 를 사용하시기 바랍니다.

char * p = NULL;
p = (char*) malloc ( 1000 );
int size = _msize(p);
memset(p, '\0', size);
free(p);

strlen()
http://www.cplusplus.com/reference/cstring/strlen/
http://forum.falinux.com/zbxe/index.php?document_srl=408105&mid=C_LIB

size_t _msize(void *memblock);
http://simple21.egloos.com/2431434
https://msdn.microsoft.com/ko-kr/library/z2s077bc.aspx

힙에 할당 된 메모리 블록의 크기를 반환 합니다.
size_t _msize(
void *memblock
);

size_t 데이터형은
_fsize_t (unsigned long integer)
Used to represent the size of a file.
IO.H,
WCHAR.H
https://msdn.microsoft.com/en-us/library/323b6b3k.aspx

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

그럼

2바이트만 먼저 읽어서 저장하고

나머지 패킷 사이즈만큼 while 루프 돌아서 읽는 방법은 쓰지 않는 것이 좋은 건가요??

shint의 이미지

--------------------------------------------------------------------------------------------
https://msdn.microsoft.com/en-us/library/323b6b3k.aspx
size_t 에 크기는 이렇습니다. 위에껀 fsize_t 였네요.

size_t (unsigned __int64 or unsigned integer, depending on the target platform)
Result of sizeof operator.
CRTDEFS.H and other include files

--------------------------------------------------------------------------------------------
지금 이야기는 데이터 배열의 크기인데.
다시 확인해보셔야 할거 같습니다.

--------------------------------------------------------------------------------------------
recv는
받은 만큼 하셔도 되고.
따로 받으셔도 됩니다.

--------------------------------------------------------------------------------------------
recv에서 멈추는 문제는
저번에 보여드린 예제소스를 참고해보세요.

--------------------------------------------------------------------------------------------
http://olc.kr/main/index.jsp
무료 강의를 하고 있습니다.

--------------------------------------------------------------------------------------------
프로그래밍 학원도 추천드립니다.

--------------------------------------------------------------------------------------------
TCP/IP 소켓프로그래밍 책과 C 책을 구입해서 따라하시기 바랍니다.

http://book.naver.com/search/search.nhn?sm=sta_hty.book&sug=pre&where=nexearch&query=TCP%2FIP+%EC%86%8C%EC%BC%93+%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

우선 리시브에서 멈추진 않습니다.

와일 루프에서도 무한 루프 상태에 빠지지 않고 있으며, 다만 배열에 문자열들이 저장이 되지 않고 있습니다...

shint의 이미지

char * pbuf = (char*) malloc ( 1000 );

int msize = _msize(pbuf);

printf("_msize : %d\n", msize);

free(pbuf);

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

balgarac1의 이미지

해보겠습니다.
근데 이 함수가 리눅스 환경에서도 동작하나요??

헤더파일 malloc.h 집어넣고 해도 빨간줄이 그어집니다만..

shint의 이미지

C++로 이렇게는 됩니다.

#include <iostream>
 
int main()
{
vector<char> p(10);
cout < < p.size() < < endl;
    return 0;
}

이거도 되는가 했는데. http://codepad.org/ 에서는 안됩니다.

윈도우 cygwin 에서는 1004가 나오네요. 4바이트가 추가되었습니다.

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
 
int main(int argc, char** argv)
{
    char * p;
    p = (char*) malloc (1000);
    int size = malloc_usable_size(p);
    printf("%d\n", size);
    free(p);
    return 0;
}
 
출력값
-149193040

------------------------------------------------
윈도우에서는 그냥 됩니다.

#include <iostream>
#include <winsock2.h> 
#include <stdio.h>
#include <stdlib.h>
 
using namespace std;

------------------------------------------------
리눅스에서는 안되나봅니다.

_msize in unix
http://www.cplusplus.com/forum/unices/58458/

vector p(10);
cout << p.size() << endl;

------------------------------------------------
malloc_size alternative on Linux and Windows
http://stackoverflow.com/questions/10959538/malloc-size-alternative-on-linux-and-windows

On Windows, things that use the MS CRT can use _msize, on Linux you could try malloc_usable_size...

------------------------------------------------
_expand() and _msize()
http://www.linuxquestions.org/questions/programming-9/_expand-and-_msize-342600/

malloc_size

------------------------------------------------
malloc()으로 할당 받은 메모리의 크기를 아는 방법
https://kldp.org/node/24528

malloc_usable_size

------------------------------------------------
OSX 10.6.2 - man page for malloc_size (osx section 3)
http://www.unix.com/man-page/osx/3/malloc_size/

size_t
malloc_good_size(size_t size);

size_t
malloc_size(const void *ptr);

------------------------------------------------
Malloc_size alternative on Linux and Windows
http://www.hitmaroc.xyz/734251-6882-malloc-size-alternative-linux-windows.html

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

백연구원의 이미지

앞뒤는 제대로 안봤는데 malloc() 쓰시려는거면
리눅스에서는 malloc.h가 아니라 stdlib.h 사용하세요

malloc.h는 표준이 아닐겁니다.


소곤소곤

jick의 이미지

C는 기본적으로 메모리 관리를 개발자에게 일임하는 언어라서, 포인터에 대해 "이 포인터가 가리키는 영역의 크기가 얼마인가" 같은 정보는 기억하고 있지 않습니다. 포인터를 사용하는 개발자가 알아서 그 길이를 기억하고 있어야 합니다.

다시 말해 포인터만 달랑 받은 다음에 "이 포인터부터 몇 바이트나 쓸 수 있나" 하고 strlen, _msize (??), 기타 함수를 불러서 길이를 재려고 하는 건 삽질입니다.

그리고 strlen은 문자열의 길이를 돌려주는 함수이지 메모리 영역의 크기를 돌려주는 함수가 아닙니다. 위에 bushi 님이 쓰신 걸 잘 읽어보세요.

댓글 달기

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