최용일님과 이중철님의 답변은 잘 봤습니다..
그런데 제가 테스트를 해 보았는데..
그것보다 더 이전의 문제점이 해결되지 않고 있습니다.. ㅠ.ㅠ
main()
var
a : array of word;
begin
fn1(@a);
edit1.text:=inttostr(a[0]);
edit2.text:=inttostr(a[1]);
end;
fn1(b : pointer);
type
tarrayword = array of word;
begin
b:=allocmem(sizeof(word)*2);
tarrayword(b)[0]:='11';
tarrayword(b)[1]:='22';
end;
이런 식으로 프로그램을 짜는게 제 목표인데요.
즉, 메인 함수에서 동적 배열이 선언되어 있는데,
서브함수에서 동적 배열을 포인터로 넘겨받아서
크기를 결정하고(메모리를 allocation하고), 값을 저장하여
메인함수에서 사용하고자 하는게 목적입니다.
그런데, 서브함수에서는 잘 저장되는데
메인함수에서 값을 사용하려고 하면
access violation 에러가 납니다.. ㅠ.ㅠ
프로그램 상에서 어떤 점이 잘못되었나요? ㅠ.ㅠ
먼저 다이나믹 및 배열은 Setlength가 더 안정적이고요
그리고 메모리 할당은 해당 스레드에서 생성하시고 소멸하는것이
정상입니다.
저도 이것땜시 골머리 썩히다가 C로 한번 해봤는데 C는 아에 처음
부터 에러 나더군요..
그리고 먼저 님께서 쓰신 문장이 어떤것이 틀렸는지 볼까요..
일전에도 말씀 드렸듯이 Dynamic Array 변수는 포인터 라고
말씀드렸죠.. 정상적인 운영법 부터 올리께요
var a : array of word;
begin <= 변수만 선언하면 a 에는 NULL 이 있습니다. 즉, 0 입니다.
SetLength(a, 10); <= 바로 이때 a 라는 변수에
힙에 10개의 word의 메모리 영역을 정하고
그 첫번째 포인터를 a에 반환합니다.
fn1(a); <= a에는 이미 포인터주소값이 담겨졌으니..
end;
fn1(b : pointer);
type
tarrayword = array of word;
begin
b:=allocmem(sizeof(word)*2); <= 이와 같은 재할당이 있으면
위와 같은 방법은 안됩니다.
tarrayword(b)[0]:='11';
tarrayword(b)[1]:='22';
end;
그런데 님께서 fn1에서 리사이징해서 쓸려고 한다. 이럴때는
function fn1 : pointer;
type
tarrayword = array of word;
begin
reslut :=allocmem(sizeof(word)*2);
tarrayword(b)[0]:='11';
tarrayword(b)[1]:='22';
end;
이렇게 하고
메인에서
var a : array of word;
begin <= 변수만 선언하면 a 에는 NULL 이 있습니다. 즉, 0 입니다.
a := fn1; <= 이런식으로 하면 a에는 할당된 주소가 담기겠죠
end;
최용일님께서 올리신 방법은 저도 많이 써요.. 위의것은 이렇게도 많이
쓴다는 것일뿐 정석은 아니에요. 최용일님께서 쓰신 방법을 전 오히려
더 많이 쓰죠 (어쩌다 실수로 3중 포인터까지 갈 경우도 있지만)
최 용일님께서 올리신 방법의 장점은 제가 서술했던 방법보다 더 가용성
이 많습니다.
main
type
tarrayword = array of word;
var a : ^tarrayword;
(이 의미는 array of word 의 첫번째 포인터가 담겨있는 포인터를
a에 정의 하겠다는 것입니다.
이 경우 a에는 값이 정의 됩니다. a에는 상기 포인터의 포인터값이
담겨져 있습니다. 바로 이 특징이 있어 더욱 가용성이 뛰어나죠
이것이 왜 이럴까는 곰곰히 생각하시면 쉽게 이해 될꺼에요);
begin
fn1(a);
end;
fn1(b : pointer);
type
tarrayword = array of word;
begin
b^:=allocmem(sizeof(word)*2); <= 이와 같은 재할당이 됩니다.
tarrayword(b^)[0]:='11';
tarrayword(b^)[1]:='22';
end;
위의 방법까지 Local, 즉 DLL을 사용하지 않을때는 잘 먹힙니다.
그러나 DLL을 사용시 위의 방법중 2, 3번째는 주의가 요망됩니다.
정확히 말하면 DLL에서 리사이즈 한것은 먹히기는 하지만
알다시피 생성을 했으면 소멸을 해야 하는데 메인 프로그램에서
소멸이 안됩니다. (메인에 소멸자 넣으면 되는것 같지만
결국 메모리 Leak걸림 <= 어떻게 안될까 저도 고민 제가 구력이
짧아서 메인에서 소멸은 못시키고 있음 DLL에서 생성하고 소멸을
합니다. )
결국 DLL에서 생성을 했으면 그 책임(생성을 한 책임)에 대한 의무
(소멸을 할 의무)도 DLL에서 해야 합니다.