2010-02-13 39 views
5

Delphi sử dụng tính tham chiếu bằng chuỗi.Chuỗi Delphi và tính tham chiếu

Điều này có nghĩa là chỉ có một cấp phát bộ nhớ cho '1234567890' và tất cả tham chiếu a, b, c, d, e và f.s?

type 
    TFoo = class 
    s: string; 
    end; 

    const 
    a = '1234567890'; 
    b = a; 
    c : string = a; 

    var 
    d: string; 
    e: string; 
    f: TFoo; 

    function GetStr1(const s: string): string; 
    begin 
    Result := s; 
    end; 

    function GetStr2(s: string): string; 
    begin 
    Result := s; 
    end; 

    begin 
    d := GetStr1(b); 
    e := GetStr2(c); 
    f := TFoo.Create; 
    f.s := a; 
    end; 
+2

(lưu ý rằng nếu bạn cho phép "sử dụng debug dcus" bạn có thể theo dõi thông qua mã, những người giúp đỡ bao gồm) –

Trả lời

9

Có, chỉ có một phân bổ trong ví dụ cụ thể của bạn. Nếu bạn đã sử dụng UniqueString, như mghie nói, hoặc nếu bạn đã xây dựng chuỗi động, sau đó bạn kết thúc với một phân bổ chuỗi mới ngay cả khi nội dung chuỗi giống như một số chuỗi khác.

Tuy nhiên, một sự thật thú vị về ví dụ cụ thể của bạn: thực sự không có bộ nhớ "được phân bổ" cho chuỗi '1234567890' chút nào. Dữ liệu cho chuỗi hằng số được lưu trữ trong hình ảnh thực thi trên đĩa và được phân trang bởi hệ điều hành khi mã truy cập nó. Nó chiếm không gian địa chỉ bộ nhớ, như là một phần của toàn bộ ánh xạ trong bộ nhớ của mô-đun thực thi, nhưng vì nó được hỗ trợ bởi thực thi gốc trên đĩa, nó không tạo thành một phần bộ nhớ cam kết của quá trình và sẽ không cần sao lưu tệp trang.

Ví dụ, chương trình này sẽ báo cáo một sự vi phạm truy cập vào chạy:

{$apptype console} 
uses SysUtils; 

const 
    s = '1234567890'; 
procedure Change(const r: string); 
var 
    p: PChar; 
begin 
    p := PChar(r); 
    p^ := 'x'; 
end; 

begin 
    try 
    Change(s); 
    except 
    on e: Exception do 
     Writeln(e.Message); 
    end; 
end. 
+0

Intresting Chúng ta phải cẩn thận khi sử dụng con trỏ – pKarelian

+0

Nếu tôi khai báo const s: string = '1234567890'; vi phạm truy cập không được nâng lên? không thể kiểm tra nó bây giờ) – pKarelian

+1

const s: string = '... làm cho không có sự khác biệt trong Delphi 7. Trình biên dịch gọi hệ thống._LStrLAsg (var dest; const source) đặt dest trỏ đến const. NHƯNG, nếu chuỗi đích là TOÀN CẦU, thì trình biên dịch gọi System._LStrAsg để thay thế. Mã nguồn lưu ý điều này được thực hiện cho khả năng tương thích DLL. –

5

vâng, các dây được ref tính, một bản sao được tạo ra chỉ khi các nội dung được sửa đổi thông qua một biến (sao chép trên viết ngữ nghĩa), biết thêm ở đây:

http://www.codexterity.com/delphistrings.htm

+0

Tốt gợi ý. Vì vậy, thông minh Delphi không mất sự refence khi chức năng trả về một chuỗi. – pKarelian

+0

http://www.codexterity.com/delphistrings.htm "WideString hoạt động chính xác như AnsiString; nó được tự động quản lý, vô hiệu hóa và * tham chiếu tính *" -> WideString không được tính tham chiếu! – kibab

+0

https://web.archive.org/web/20100323193851/http://www.codexterity.com/delphistrings.htm là sai? Từ RADStudio "Các loại WideString đại diện cho một chuỗi phân bổ động của các ký tự Unicode 16-bit.Trong một số khía cạnh nó tương tự như AnsiString. Trên Win32, WideString là tương thích với các loại COM BSTR. WideString là thích hợp để sử dụng trong các ứng dụng COM. WideString không được tính tham chiếu, và vì vậy UnicodeString linh hoạt hơn và hiệu quả hơn trong các loại ứng dụng khác. " – robocat

6

Ngoài nhỏ đến số answer by jxac:

Bản sao cũng sẽ được tạo khi UniqueString() được gọi bằng mã, khi một ký tự trong chuỗi được truy cập bởi [] và khi chuỗi được nhập vào PChar. Điều này xảy ra ngay cả khi PChar và phần tử chuỗi sẽ chỉ được đọc. Điều quan trọng là phải biết cách buộc một chuỗi duy nhất từ ​​một chuỗi có khả năng chia sẻ, bởi vì có các hàm API Windows không được gọi bằng con trỏ char chỉ đọc, mà PChar đến một hằng số chuỗi là. Trong trường hợp đó, hằng số cần phải được sao chép vào một biến đầu tiên, do đó, việc đúc nó sẽ trả về một PChar trỏ đến bộ nhớ có thể ghi.

+0

Có. Tôi nhận thấy rằng khi tôi gọi hàm dll với tham số PChar trả về dữ liệu :-( – pKarelian

Các vấn đề liên quan