2009-09-22 5 views
2

저는 한 시간 전에 책을 읽었으며 아직도 내 응용 프로그램에서 무슨 일이 일어나는지 알지 못합니다. newdelete과 함께 객체의 인스턴스를 사용하고 있으므로 메모리를 직접 관리해야합니다. 내 애플리케이션은 오랜 시간 동안 작동해야하므로 메모리 소비를 적절하게 관리하는 것이 중요합니다.C++에서 포인터를 전달해도 여전히 개체가 복사됩니까?

다음은 데이터 패킷을 덤프하는 데 사용하는 정적 기능입니다.이 기능은 PC와 I/O 보드간에 양방향으로 전송됩니다. 데이터 패킷은 BYTE의 배열이며 DCCmd 또는 DCReply (모두 DCMessage 추상 클래스 구현) 객체로 캡슐화됩니다.

void DebugTools::dumpBytes(BYTE* bytes, short length) 
{ 
    printf("  |---DUMPING DATAPACKET refId: %d ....\n", &bytes); 
    for(short i=0; i<length; i++){ 
     printf("  | B%d | %.2X\n", i, bytes[i]); 
    } 
    printf("  |---END DUMP   refId: %d ....\n", &bytes); 
} 

그런 다음이 사용하는 경우가있다 : 나는 DCCmd 객체를 생성하고 전송하기 위해 보내는 메시지 큐에 추가합니다. "펌프"(무한 루프)는 보낼 편지함을 검사하고 임의의 후보를 IOConnector 싱글 톤 개체로 전달합니다.

DCCmd* cmd = new DCCmd(DIG_CMD_SELFTEST_RES); 
cmd->add(param); 
printf("cmdSelfTest()\n"); //HACK 
BYTE* cmda = cmd->getBytes(); //HACK 
DebugTools::dumpBytes(cmda, cmd->getLength()); //HACK 
sendMsg(cmd); 

... 큐에 추가 :

bool DC::sendMsg(DCMessage* msg) 
{ 
    if(isOnline()){ 
     outbox->add(msg); 
     return true; 
    } else { 
     return false; 
    } 
} 

큐에 추가가 커넥터 클래스에서 (void add(DCMessage* msg);

이루어집니다 정말 무엇을보고 그 dumpBytes()의 다른있다 전송 예정)

출력은 다음과 같습니다.

TESTING MESSAGE QUEUES .... 
cmdSelfTest() 
     |---DUMPING DATAPACKET refId: 2489136 .... 
     | B0 | C6 
     | B1 | A1 
     | B2 | 00 
     | B3 | 01 
     | B4 | 10 
     | B5 | 00 
     | B6 | 01 
     | B7 | 78 
     |---END DUMP   refId: 2489136 .... 
    adding to queue: 2488884 
    queues: inbox (0), outbox (1) 
send: sending candidates.... 
    sending 2489164 .... 
    >->-> ... 
     |---DUMPING DATAPACKET refId: 2488704 .... 
     | B0 | C6 
     | B1 | A1 
     | B2 | 00 
     | B3 | 01 
     | B4 | 10 
     | B5 | 00 
     | B6 | 01 
     | B7 | 78 
     |---END DUMP   refId: 2488704 .... 
Packet sent! 
. ((second iteration of the pump)) 
    queues: inbox (0), outbox (1) 
send: sending candidates.... 
    sending 2489164 .... 
    >->-> ... 
     |---DUMPING DATAPACKET refId: 2488704 .... 
     | B0 | C6 
     | B1 | A1 
     | B2 | 00 
     | B3 | 01 
     | B4 | 10 
     | B5 | 00 
     | B6 | 01 
     | B7 | 78 
     |---END DUMP   refId: 2488704 .... 
Packet sent! 

누군가가 한 블록에서 다른 블록으로 전달할 때마다 참조가 다른 이유는 무엇입니까? 이것은 메모리 소비의 의미는 무엇입니까? 내가 메모리를 복제하지 않도록하려면 어떻게해야합니까? 감사.

답변

5

가변 바이트는 데이터에 대한 포인터, 즉 데이터의 메모리 위치이다. 하지만 인쇄하는 것이 아닙니다.이 포인터가 위치한 주소, 즉 포인터가 전달 된 스택의 주소를 인쇄하고 있습니다.그래서

printf("  |---DUMPING DATAPACKET refId: %d ....\n", &bytes); 

printf("  |---DUMPING DATAPACKET refId: %d ....\n", bytes); 
+0

사실,이 배열의 동일한 복사본으로 작업하고 있는지 여부를 확인한이 모든 상황을 수정하면 응용 프로그램 전체에서 동일한 주소가 출력됩니다. 포인터는 의도 한대로 실제로 작동합니다. –

1

바이트 변수는 포인터, 당신은 전달 된 포인터에서 복사 한 새로운 포인터를 얻을이 경우, dumpBytes에서 함수 매개 변수이지만, 여전히 스택에 자신의 주소와 새, 입니다 , 주소가 인 것은 매번 다를 것입니다. 동일한 장소에서 호출되지 않고 스택 주소가 순수한 우연으로 동일하지 않으면 예외가됩니다.

+0

내가 펌프의 두 번째 반복을 추가, 그래서 두 번째 패스에 값이 같은 방법을 발견했습니다해야합니다. 그래서 나는 매번 그런 것은 아니라고 생각합니다. 어딘가에 뭔가를 저장해야합니다. –

+0

스택에서 같은 위치에있을 가능성이 큽니다. – Kylotan

+0

아, 내가 정확히 스택 및 모든 acquinted 아니에요 =) 인정 –

1

dumpBytes를 호출하면 참조 전달 대신 전달 바이 패스를 사용하여 바이트를 전달했습니다.

이렇게하면 포인터가 새 이되어 dumpBytes의 수명 동안 BYTES가 만들어집니다. 귀하의 시스템에 따라 이것은 8,16,32,64 바이트 등이 될 것입니다. 다른 말로하면, 당신이 정말로 아주 엄격한 메모리 제약이 없다면 문제가되지 않을 것입니다.

+0

주로 바이트 배열 메모리 소비, 포인터가 궁금 해서요. –

+0

@Omer, 복사되는 유일한 것은 배열 자체가 아니라 배열에 대한 포인터입니다 – Glen

+0

예. 지금 당신의 요지를 봅니다. 그래서 포인터가 내 dumpBytes() 함수의 바이트와 같이 범위를 벗어날 때 자동으로 해제된다고 추측 할 수 있습니까? –

관련 문제