AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Zugriff auf Record-Eigenschaft nicht möglich
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf Record-Eigenschaft nicht möglich

Ein Thema von CalganX · begonnen am 15. Mai 2009 · letzter Beitrag vom 18. Mai 2009
Antwort Antwort
Seite 1 von 2  1 2      
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#1

Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 11:15
Hallo zusammen,

ich habe folgendes Record:
Delphi-Quellcode:
AWSTRING = record
  len: int32_t;
  value: WideString;
end;
Nun will ich mit Hilfe eines File-Streams aus einer Datei dieses Record füllen:
Delphi-Quellcode:
function fread_AWSTRING(var destination: AWSTRING; const fs: TFileStream): size_t;
var
  temp: uint16_t;
  i: integer;
begin
  Result := fread_be_int32(destination.len, 1, fs);
  if ((destination.len) > 0) then begin
    destination.value := StringOfChar(#00, destination.len);
    for i := 0 to destination.len - 1 do begin
      fread_be_uint16(temp, 1, fs);
      destination.value[i+1] := WideChar(temp);
    end;
  end;
end;
In Zeile 8 schmeißt mir der Debugger aber eine Zugriffsverletzung um die Ohren. Und das ist unabhängig davon, was ich da mache. Jeder Zugriff auf destination.value schlägt fehl, während der Zugriff auf destination.len möglich ist. Auch wenn ich Zeile 8 ganz weg lasse, kriege ich bei destination.value[i+1] := WideChar(temp); eine Zugriffsverletzung (temp hat mit 101 aber einen korrekten Wert - daran kann es also nicht liegen).

Kann sich das jemand bzw. mir erklären?

Gruß
Christopher

PS: Das analoge Einlesen eines Strings (destination.value hat da den Typ String) funktioniert problemlos.
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#2

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 11:22
Da WideString nicht finalisierbar istr steht bei Value nur ein Zeiger. du müsstest mit einer Hilfsvariablen arbeiten
Markus Kinzler
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#3

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 11:24
versuch mal statt StringOfChar ein
SetLength(destination.value, destination.len);
$2B or not $2B
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#4

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 11:28
Hallo,

Zitat von himitsu:
SetLength(destination.value, destination.len);
wie gesagt: Es ist unabhängig davon, was ich in Zeile 8 mache. Habe SetLength schon probiert und führt zum gleichen Fehler.

Zitat von mkinzler:
Da WideString nicht finalisierbar istr steht bei Value nur ein Zeiger. du müsstest mit einer Hilfsvariablen arbeiten
Ganz so einfach scheint das aber auch nicht zu gehen.
Delphi-Quellcode:
function fread_AWSTRING(var destination: AWSTRING; const fs: TFileStream): size_t;
var
  temp: uint16_t;
  i: integer;
  temps: WideString;
begin
  Result := fread_be_int32(destination.len, 1, fs);
  if ((destination.len) > 0) then begin
    SetLength(temps, destination.len);
    for i := 0 to destination.len - 1 do begin
      fread_be_uint16(temp, 1, fs);
      temps[i+1] := WideChar(temp);
    end;
    destination.value := temps;
  end;
end;
Da fliegt mit in der letzten Zeile eine EOutOfMemory-Exception um die Ohren.

Gruß
Christopher
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#5

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 12:13
Kann es sein, dass der Aufrufer der Funktion bereits einen defekten destination Parameter reingibt, also der WideString auf eine undefinierte Speicheradresse zeigt?
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#6

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 12:20
Hallo jbg,

das Rekord ist in keiner Weise initialisiert. D.h. es ist einfach eine lokale Variable in einer Prozedur, die durch drei Aufrufe bis an fread_AWSTRING gegeben wird:

Delphi-Quellcode:
type
  generic_data_header = record
    data_type_id: ASTRING;
    unique_file_id: ASTRING;
    date_time: AWSTRING;
    locale: AWSTRING;
    n_name_type_value: int32_t;
    name_type_value: array of nvt_triplet;
    n_parent_headers: array of Pointer;
  end;

function Read_Generic(const filename: string): boolean;
var
  fs: TFileStream;
  my_data_header: generic_data_header;
begin
  Result := false;

  fs := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone);
  try
    read_generic_data_header(my_data_header, fs);
  finally
    FreeAndNil(fs);
  end;

  Result := true;
end;

function read_generic_data_header(var data_header: generic_data_header; fs: TFileStream): integer;
begin
  Result := fread_ASTRING(data_header.data_type_id, fs) or
            fread_ASTRING(data_header.unique_file_id, fs) or
            fread_AWSTRING(data_header.date_time, fs) or
            fread_AWSTRING(data_header.locale, fs);
end;
Da wir uns aber ja unter Delphi befinden, habe ich nicht den Drang verspürt für den WideString großartig Speicher zu belegen. Wenn ich eine lokale Widestring-Variable, die nicht in einem Array ist, fülle, dann brauche ich ja auch nix zu belegen, sondern es funktioniert dank Compiler-Magic.

Gruß
Christopher
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#7

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 13:02
Die Methode fread_AWSTRING hat imo keinen Fehler, es könnte eher an fread_be_int32 oder fread_be_uint16 liegen. Liefern die das richtige zurück? (Länge des auszulesenden Strings und einzelne Zeichen)
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#8

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 13:53
Hallo Stefan,

ja, eigentlich schon. Und der Fehler passiert ja direkt beim ersten Zugriff auf destination.value.

Ich bin nur jetzt nicht mehr im Büro - erst am Montag wieder. Ich gucke dann noch mal drüber.

Gruß
Christopher
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.027 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#9

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 15. Mai 2009, 16:03
Poste dann mal bitte ein kleines Programm, in dem der Fehler nachstellbar ist, mein Test mit einem solchen Record schlug nämlich nicht fehl. (Delphi7)
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#10

Re: Zugriff auf Record-Eigenschaft nicht möglich

  Alt 18. Mai 2009, 09:23
Hallo,

das Problem liegt wohl nicht in den fread_*-Methoden. Greife ich nämlich noch vor dem Lesen auf die Eigenschaft zu:
Delphi-Quellcode:
function read_generic_data_header(var data_header: generic_data_header; fs: TFileStream): integer;
begin
  fread_ASTRING(data_header.data_type_id, fs);
  fread_ASTRING(data_header.unique_file_id, fs);
  fread_AWSTRING(data_header.date_time, fs); // Hier wird nix gelesen, da die Länge = 0 ist
  data_header.locale.value := '-----'; // <--- hier kommt die Exception
  fread_AWSTRING(data_header.locale, fs);

  Result := 1;
end;
Erhalte ich schon dort eine EOutOfMemory-Exception.

Noch mal die Typ-Definitionen:
Delphi-Quellcode:
type
  // C-Typedefs
  int8_t = Shortint;
  uint8_t = Byte;
  int16_t = Smallint;
  uint16_t = Word;
  int32_t = integer;
  uint32_t = longword;
  float32_t = Single;
  uchar = uint8_t;

  AWSTRING = record
    len: int32_t;
    value: WideString;
  end;

  generic_data_header = record
    data_type_id: ASTRING;
    unique_file_id: ASTRING;
    date_time: AWSTRING;
    locale: AWSTRING;
    n_name_type_value: int32_t;
    name_type_value: array of nvt_triplet;
    n_parent_headers: array of Pointer;
  end;
Irgendwelche Vorschläge?

Gruß
Christopher

PS: Ich weiß im Moment nicht, wie ich ein Beispielprogramm bereit stellen sollen, da ich die Datei, aus der gelesen werden soll, nicht veröffentlichen kann.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:27 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz