memcpy 가 이상합니다. 메모리 문제인가요??

passion의 이미지

memcpy (XX_PABC->STEP_MEMBER, "0004",
sizeof(XX_PABC->STEP_MEMBER));
위와 같이, 선언된 구조체 멤버에 어떤 값을 copy 하려하는데 값을 할당하지
못합니다.
구조체의 STEP_MEMBER의 바로전 멤버와 (SUB_CUST_ID)
바로뒤 멤버의(RM_COA_ID) 값은 변형이 되지만,
STEP_MEMBER 의 값은 어쩐 이유인지 변형이 되지 않습니다.
여러가지 해결책을 궁리한 끝에,
첨부된 소스의 내용중 sub function (MAKE_PABC) 내의
char pointer 변수가 선언된 부분이 있는데 이는 값을 할당하지 않더라도
단지 선언만 해주고 malloc 으로 메모리만 확보해줌으로서 고민하고 있는
문제가 해결됐습니다.
또 다른 편법으로는 char pointer를 선언하고 그값에 원하는 값을 memcpy
하고 ("0004") 그 포인터변수를 구조체에 memcpy 하니까 되더군요.
또 직접 XX_PABC->STEP_MEMBER 에다 for.. loop 을 이용해서
일일이 한자리씩 값을 부여했더니 되더군요....
왜 구조체 배열에 바로 "0004"를 memcpy 하믄 안댈까요?

왜 이런 현상이 나타나는지 알고 싶습니다.

참고로 XX_PABC->STEP_MEMBER 의 메모리 주소값을 확인해본 결과
804396431 번지 였고
그 뒤를 잇는 RM_COA_ID 의 주소값은 804396436 번지였습니다.
804396436 번지의 값은 handling이 되는데 왜 그 앞번지의 값은
handling이 되질 않는지 도무지 모르겠습니다.
구조체가 읽어들이는 data는 source에 comment 로 적어놨습니다.
찬찬히 살펴보시고 마구마구 꼬집어 주십시오. 부탁드립니다.

File attachments: 
첨부파일 크기
파일 memcpy_test.c3.4 KB
Image icon 테스트용.JPG34.12 KB
mastercho의 이미지

근데 적어도 "0004"를 할당하기 위해선

4바이트가 아니라 5바이트가 필요할거 같은데요

널문자도 넣어서요

정확하게 소스를 보지 않았지만

널문자를 넣지 않아서 생기는 문제 같다는 느낌이 듭니다

널문자를 빼고 카피한다음 쓰다보면 문자 인식할때

배열의 메모리를 넘어선 부분이 다른 문자로 채워져 있어서

문자열의 끝을 제대로 파악하지 못하는 경우를 꽤 본거 같네요

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

passion의 이미지

♣ memory copy after value is [0003]
▣ array copy after value is [0004]
◆[0332010]/[XXXXXXX]/[0004][0000000000]

STEP_MEMBER 의 자리수는 4자리이고 NULL을 포함하지 않습니다.

첫번째 [0003] 부분은 memcpy 을 이용해서 값을 할당한경우고,
두번째 [0004] 는 for .. Loop 로 일일히 한자리씩 값을 할당한 것을
출력했습니다. 왜 memcpy 가 안댈까요..ㅠㅠ

mastercho의 이미지

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

#include <iostream>

using namespace std;
/* 구조체가 읽어들이는 data는 이렇습니다.
10,2003093001,0000000000000000000000000,0000000,0704,0000000,20030930,000,0,+00000000000000,+00000000000001,+00000000000000,0000,0000854,0332050,00000000000,419716709,0003,0000000000,00000000,
*/

typedef struct A {
	char	TARGET_TABLE_CODE [ 2]; char fill_01  [1];
	char	IDENTITY_CODE     [10]; char fill_02  [1];
	char	ID_NUMBER         [25]; char fill_03  [1];
	char	GL_ACCOUNT_ID     [ 7]; char fill_04  [1];
	char	ORG_UNIT_ID       [ 4]; char fill_05  [1];
	char	COMMON_COA_ID     [ 7]; char fill_06  [1];
	char	AS_OF_DATE        [ 8]; char fill_07  [1];
	char	ISO_CURRENCY_CD   [ 3]; char fill_08  [1];
	char	IDENTITY_CODE_CHG [ 1]; char fill_09  [1];
	char	AMOUNT            [15]; char fill_10  [1];
	char	ACTIVITY_VOLUME   [15]; char fill_11  [1];
	char	ACTIVITY_AMOUNT   [15]; char fill_12  [1];
	char	GAMANG_ORG_ID     [ 4]; char fill_13  [1];
	char	IS_COA_ID         [ 7]; char fill_14  [1];
	char	ACT_BP_ID         [ 7]; char fill_15  [1];
	char	SRC_GA_ID         [11]; char fill_16  [1];
	char	SUB_CUST_ID       [ 9]; char fill_17  [1];
	char	STEP_MEMBER       [ 4]; char fill_18  [1];
	char	RM_COA_ID         [10]; char fill_19  [1];
	char	TP_COA_ID         [ 8]; char fill_20  [1];
	char    line_feed         [ 1];
	} ST_PABC;

void MAKE_PABC(ST_PABC *XX_PABC);

int main()
{
	FILE *src;
	ST_PABC XX_PABC;

	//src = fopen("./TEST.SAM","rb");
	//if (src == NULL) { printf("file open error \n"); exit(1); }

	//w/hile(fread(&XX_PABC,sizeof(ST_PABC),1,src) != NULL)
	//{
		MAKE_PABC(&XX_PABC);
	//}
}

void MAKE_PABC(ST_PABC *XX_PABC)
{
	int i;
	char step_member[10];
	cout<<"시작"<<endl;

	memset(step_member,0x00,sizeof(step_member));
	memcpy(step_member,"0004",4);

//	if ( memcmp(XX_PABC->ACT_BP_ID,"0332010",7) == 0 || memcmp(XX_PABC->ACT_BP_ID,"0332020",7) == 0 ||
//		memcmp(XX_PABC->ACT_BP_ID,"0332030",7) == 0 || memcmp(XX_PABC->ACT_BP_ID,"0332040",7) == 0 ||
//		memcmp(XX_PABC->ACT_BP_ID,"0332050",7) == 0 )
//	{
		printf("♣ [%u][%.*s]/[%u][%.*s]/[%u][%.*s]/[%u] \n",&XX_PABC->ACT_BP_ID,  sizeof(XX_PABC->ACT_BP_ID),XX_PABC->ACT_BP_ID,
			&XX_PABC->IS_COA_ID,  sizeof(XX_PABC->IS_COA_ID),XX_PABC->IS_COA_ID,
			&XX_PABC->STEP_MEMBER,sizeof(XX_PABC->STEP_MEMBER),XX_PABC->STEP_MEMBER,
			&XX_PABC->RM_COA_ID);

		memcpy (XX_PABC->ACT_BP_ID, "0332010", sizeof(XX_PABC->ACT_BP_ID));
		memcpy (XX_PABC->IS_COA_ID, "XXXXXXX", sizeof(XX_PABC->IS_COA_ID));

		/*-- 문제시 되는 부분입니다. 왜 이구문이 먹혀들지 않는지...
		XX_PABC->STEP_MEMBER 의 주소값을 못찾는것도 아니고, memory lock 이 걸린것도 아니구요.. --*/
		memcpy (XX_PABC->STEP_MEMBER, "0004",  sizeof(XX_PABC->STEP_MEMBER));
		printf("◇ memory copy after value is [%.*s]\n",sizeof(XX_PABC->STEP_MEMBER),XX_PABC->STEP_MEMBER);
		
		cout<<"확인 : "<<XX_PABC->STEP_MEMBER<<endl;
		
		for(i=0;i<sizeof(XX_PABC->STEP_MEMBER);i++)
			XX_PABC->STEP_MEMBER[i] = step_member[i];

		printf("▣ array copy after value is [%.*s]\n",sizeof(XX_PABC->STEP_MEMBER),XX_PABC->STEP_MEMBER);

		printf("◆ [%.*s]/[%.*s]/[%.*s][%.*s] \n",sizeof(XX_PABC->ACT_BP_ID),XX_PABC->ACT_BP_ID,
			sizeof(XX_PABC->IS_COA_ID),XX_PABC->IS_COA_ID,
			sizeof(XX_PABC->STEP_MEMBER),XX_PABC->STEP_MEMBER,
			sizeof(XX_PABC->RM_COA_ID), XX_PABC->RM_COA_ID);
//	}


}

잘은 모르겠지만 0004가 들어가지 않은건 if문 에서 false가 되서

그런거 같네요 -_-;

일단 실행해보니 제대로 값은 나옵니다 0004가요

그림을 참고하세요

[그리고 이상한 문자가 나온건 구조체를 0으로 모두 초기화 시키지 않아서 나온겁니다]

댓글 첨부 파일: 
첨부파일 크기
Image icon 0바이트

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

큰괭이의 이미지

typedef struct A { 
                .
                .
                .
   char   STEP_MEMBER       [ 4]; char fill_18  [1]; 
                .
                .
                .
} ST_PABC;

에서..

memcpy (XX_PABC->STEP_MEMBER, "0004",  sizeof(XX_PABC->STEP_MEMBER));

를 하시는데...

여기서 sizeof(XX_PABC->STEP_MEMBER)는... 4BYTE가 아니라..
char * 의 사이즈가 되는거 아닌가요?

그런것으로 알고 있는데.. 쩝....

^.^
[/code]

?

mastercho의 이미지

Quote:
여기서 sizeof(XX_PABC->STEP_MEMBER)는... 4BYTE가 아니라..
char * 의 사이즈가 되는거 아닌가요?

그런것으로 알고 있는데.. 쩝....


아닙니다

스텍메모리에 , 구조체의 멤버 변수의 배열로 잡혀있는 저 포인터는 sizeof 시 자기가 가지고 있는 배열의 크기를 리턴합니다

따라서 4Byte를 리턴하는게 맞고요

char* 형도 일반적인 32비트 컴퓨터에서는

4Byte 크기를 가집니다 -_-;

결과적으로는 같지요 ...

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

lasher의 이미지

이상하네요. 제 거는 제대로 동작하는군요.

소스를 다운 받은 다음 두 가지 플랫폼(윈도, 리눅스 각기 다른 컴퓨터)에서 돌려 봤는데 모두 "0004"로 나오는군요.

리눅스 머신

$ memcpy_test
¢A [3221224185][0332050]/[3221224177][0000854]/[3221224215][0003]/[3221224220]
¡Þ memory copy after value is [0004]
¢A array copy after value is [0004]
¡ß [0332010]/[XXXXXXX]/[0004][0000000000]

윈도 머신

] memcpy_test
♣ [1244997][0332050]/[1244989][0000854]/[1245027][0003]/[1245032]
◇ memory copy after value is [0004]
▣ array copy after value is [0004]
◆ [0332010]/[XXXXXXX]/[0004][0000000000]

아무래도 문제는 다른데에 있는 것 같습니다. 몇 군데 다른 환경에서 여러 번 테스트를 해 보심이 어떨 듯.

그리고, 메인 루틴에 fread로 읽어 들이는 부분에 잘못된 점이 있네요. fread의 반환값은 size_t (양의 정수)타입이며, 읽혀진 ojbect 갯수(여기서는 1)를 반환하지요. 처음에 컴파일 하더니 에러/경고가 뜨더군요.

while(fread(&XX_PABC,sizeof(ST_PABC),1,src) != NULL)

이렇게 고치셔야 할 듯.

while(fread(&XX_PABC,sizeof(ST_PABC),1,src) > 0)

댓글 달기

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