![]() |
Dynamische Arrays ... kleines Problem!
Servus allerseits! :)
Ich habe schlicht und einfach nur die Frage... Ich habe folgendes:
Delphi-Quellcode:
So, nun möchte ich einen Array erstellen und dem die Größe
Test: Longint;
von "Test" geben ... :
Delphi-Quellcode:
Egal, welche Werte sich in "Test" befinden, ich habe
SetLength(MeinArray, Trunc(Test));
das Gefühl das dies so nicht geht - bekomme immer exceptions. :( Kann mir jemand einen Tipp geben? (PS: Test MUSS LongInt sein ... oder muss ich das konvertieren? Irgendwie? :)) |
Re: Dynamische Arrays ... kleines Problem!
Hmm ... meine Glaskugel sagt:
Delphi-Quellcode:
funktioniert.
var
Test : longint; MeinArray : array of word; begin Test := 12345; setlength(MeinArray,trunc(Test)); Welche Exception bekommst du denn? Ein bischen mehr Code würde uns sicher auch weiter helfen. |
Re: Dynamische Arrays ... kleines Problem!
Warum trunc? Test ist doch schon ein Integer.
|
Re: Dynamische Arrays ... kleines Problem!
Zitat:
248316*SizeOf(SmallInt) = 485 KB sollte also kein Problem darstellen Die Grenzen für dynamische Arrays liegen bei High(Integer) div SizeOf(FeldGröße) und natürlich dem zur Verfügung stehenden, zusammenhängenden, virtuellen Speicher. also bei dir $7FFFFFFF div 2 = maximal 1.073.741.823 Und ohne weiteren Code deinerseit kann dir keiner helfen ... das mit dem TRUNC wurde schon gesagt und sonst ist hier kein Fehler zu finden. |
Re: Dynamische Arrays ... kleines Problem!
Arrays sind nullbasiert.
Das erste Element steht nicht in Index 1, sondern in index 0. Das letzte Element steht also auch nicht in length(array), sondern in length(array)-1 bzw. high(array). Vielleicht ist das das Problem. |
Re: Dynamische Arrays ... kleines Problem!
Zitat:
Gruß Der Unwissende |
Re: Dynamische Arrays ... kleines Problem!
Danke, an alle! Das Problem konnte ich mittlerweile beheben! Aber wie das so ist - prompt hat man ein neues :wink: :
Beispiel:
Delphi-Quellcode:
(...)
LoopBuffer: array of SmallInt;
SetLength(LoopBuffer, Header.DataBytes); LoopBuffer := 0;
Delphi-Quellcode:
..bekomme ich grundsätzlich den EInOutError #1784 ... (das der zur Verfügung gestellte Puffer für diese Operation nicht gültig ist)
BlockWrite(F, LoopBuffer, Length(LoopBuffer));
:shock: Und da Frage ich mich nun, warum?? BlockWrite benötigt für "Count" (anzahl der Records, quasi) einen Wert vom Typ Integer. So. Mein "Length(LoopBuffer)" GIBT einen Integerwert zurück! (Hab ich bereits via Bildschirmausgabe getestet). Wo zum Henker ist also das verdammte Problem hier? :wall: :gruebel: :( |
Re: Dynamische Arrays ... kleines Problem!
Zitat:
Die Größe ist soweit auch nicht der Fehler. Versuch aber mal die Adresse des ersten Elements zu verwenden statt den Zeiger auf das Array:
Delphi-Quellcode:
Nebenbei bemerkt, Count sollte imho die Anzahl von Byte angeben, die geschrieben werden und hat nichts mit Records zu tun!
BlockWrite(F, @LoopBuffer[0], Length(LoopBuffer));
Gruß Der Unwissende |
Re: Dynamische Arrays ... kleines Problem!
Danke! :)
Mit dem ":= 0" - ööhm...dachte, so.... zur Initialisierung, quasi? :oops: Hmm habs mit dem Pointer getestet, Allerdings kann ich es nicht kompilieren, bekomme dann immer die Fehlermeldung das er noch eine Variable benötigt... :? Nun dachte ich wenn ich direkt LoopBuffer[0] angebe, würde er quasi bei Eintrag 0 starten... aber irgendwie.... ist dann nichts mehr in meinem WAV-File :mrgreen: :gruebel: |
Re: Dynamische Arrays ... kleines Problem!
Das @ muss weg, das ist ein var-Parameter.
Zitat:
|
Re: Dynamische Arrays ... kleines Problem!
Huch, hab ich jetzt "^" und "@" verwechselt? ^ war doch ein Pointer? :)
Ja, und einfach nur mit "LoopBuffer[0]" - das habe ich versucht. Der Fehler ist endlich weg, aber das Resultat: Stille im WAV-file :gruebel: |
Re: Dynamische Arrays ... kleines Problem!
Jein.
Delphi-Quellcode:
Hier: ^ vor einem Typ zur Deklaration eines Zeigertyps
type
PInteger = ^Integer;
Delphi-Quellcode:
Hier: ^ nach einem Pointer zur Dereferenzierung eines Zeigers
var I: Integer;
PI: PInteger; begin I:=PI^; end;
Delphi-Quellcode:
var I: Integer;
PI: PInteger; begin PI:=@I; end; Hier: @ vor einer Variable zur Erzeugung eines Pointers. |
Re: Dynamische Arrays ... kleines Problem!
@sonicfire:
Zum Initialisieren eines arrays würd ich ZeroMemory hernehmen. |
Re: Dynamische Arrays ... kleines Problem!
Danke an alle erstmal soweit! :)
Dummerweise gibts schon wieder ein neues Problem ;) Hachja....*seufz* Wenn ich den Inhalt vom LoopBuffer Array (SmallInt´s) in mein WAV-file schreiben will, unter Verwendung von:
Delphi-Quellcode:
...kommt nur murks bei raus! seufz...!
BlockWrite(F, LoopBuffer[0], Header.DataBytes);
Man höre hier: ![]() Bild dazu (Code)...achtung, newbie-code ;) ![]() |
Re: Dynamische Arrays ... kleines Problem!
![]() wie man sieht, wenig code - aber irgendwas muss wohl total falsch sein? |
Re: Dynamische Arrays ... kleines Problem!
man hätte auch den code als text posten können...
|
Re: Dynamische Arrays ... kleines Problem!
Nicht persönlich nehmen, aber man hätte diesen Beitrag auch lassen können ;) Denn das hilft mir nicht.
|
Re: Dynamische Arrays ... kleines Problem!
Seufz... wer mir mit dem Code hilft, bekommt 10 Euro :roll: :wink:
|
Re: Dynamische Arrays ... kleines Problem!
ein smallint ist 2 bytes gross, also musst du auch doppelt so viele bytes schreiben wie Header.DataBytes angibt:
Code:
und steig zum arbeiten mit dateien lieber auf TFileStream um, kommt besser ;)
BlockWrite(F, LoopBuffer[0], Header.DataBytes*SizeOf(SmallInt));
edit: Kontonummer kommt dann per PN :P |
Re: Dynamische Arrays ... kleines Problem!
Danke, BlackJack! :) Leider hat das nur nichts geändert :(
|
Re: Dynamische Arrays ... kleines Problem!
hast du dran gedacht das bei allen BlockReads/BlockWrites zu ändern? weil sowohl Buffer als auch LoopBuffer sind arrays of SmallInt, aber du liest/schreibst immer Length() viele bytes aus, aber du musst immer Length() SmallInts auslesen :warn:
|
Re: Dynamische Arrays ... kleines Problem!
Zitat:
|
Re: Dynamische Arrays ... kleines Problem!
:lol: :roll: Oh man, und jetzt weiss keiner mehr weiter ... *grins*.
Das kann doch alles nicht sein :x Der Code müsste eigtl. doch funzen - tut es aber nicht ... seufz |
Re: Dynamische Arrays ... kleines Problem!
Soll ich demjenigen der das zum laufen bekommt 100 Euro zahlen? Lol! Gibts dann eine Antwort?
Man, echt - ich glaub das alles nicht ;) Kann doch nicht sein das ich hier ein unlösbares Problem habe.....! NADA! |
Re: Dynamische Arrays ... kleines Problem!
:roll: nich soviel pushen
|
Re: Dynamische Arrays ... kleines Problem!
Arrays speichern/laden? Nichts leichter als das:
Delphi-Quellcode:
Was du jetzt tun musst:type TMyTypeArray = array of TMyType; //TMyType durch fundamentalen typen ersetzen (z.B. Integer, oder ein record mit fudamentalen Typen) procedure SaveToFile(Filename: string; Value: TMyTypeArray); begin with TFilestream.Create(FileName, fmOpenRead) do try WriteBuffer(Value,length(Value) * sizeof(TMyType)); finally Free; end; end; procedure SaveToFileAppend(Filename: string; Value: TMyTypeArray); begin with TFilestream.Create(FileName, fmOpenWrite) do try Position := Size; WriteBuffer(Value,length(Value) * sizeof(TMyType)); finally Free; end; end; procedure LoadFromFile(FileName: string; out Value: TMyTypeArray;Start: Integer = 0); begin with TFilestream.Create(FileName, fmOpenRead) do try Position := Start; setlength(Value, Size-Position); ReadBuffer(Value,length(Value)); finally Free; end; end; 1. Diesen Code in dein Programm kopieren 2. TMyType (alle Vorkommen!) durch SmallInt ersetzen (allerdings solltest du anstatt "SmallIntArray" evtl. "TSmallIntArray" erwägen, das ist so üblicher) 3. Deinen LoopBuffer als SmallInt deklarieren Der dritte Schritt ist der wichtigste, der Compiler reisst dir sonst den Arsch auf! Dann kannst du (gerne auch in SaveTheWave) einfach SaveToFileAppend aufrufen, um an deinen Header (für den du das Verfahren mit dem FileStream gerne übernehmen kannst, du könntest auch z.B. den zusätzlichen Parameter "Header" ins savetofile einfügen, und den zuerst schreiben). Wenn dir ![]() ![]() |
Re: Dynamische Arrays ... kleines Problem!
@EDatabaseError: Verzeihung! :oops:
@DGL-Luke: Vielen Dank!! :) Mal sehen, inwieweit ich das so hinbekomme ;) Wofür steht eigtl. das ewige "T"? :stupid: "T"ype? *grins* |
Re: Dynamische Arrays ... kleines Problem!
Jop. Ist bei Pascal einfach Standard, damit man Typen besser von Variablen unterschieden kann.
|
Re: Dynamische Arrays ... kleines Problem!
@DGL-Luke: Noch eine (blöde?) Frage ? Wie komme ich über TStream eigentlich an meine WAV-Daten heran um sie zu manipulieren?
Quasi: For b=0 to endeVomBuffer "WaveData.Buffer[b] := wasauchimmer" ? :) |
Re: Dynamische Arrays ... kleines Problem!
Naja...
Delphi-Quellcode:
Das sizeof(TWavHeader) mache ich, damit er erst nach dem header lädt. Ich habe in dienem Quellcode ja gesehen, dass du zuerst einen Header schreibst. Den überspringe ich damit.
procedure WasMachenMitWavVonDatei(filename: string);
var Wavbuffer: TSmallIntArray; i: Integer; begin //laden LoadFromFile(filename, Wavbuffer, sizeof(TWavHeader)+1); //was machen for i := 0 to high(Wavbuffer) do Wavbuffer[i] ..... end; |
Re: Dynamische Arrays ... kleines Problem!
Dank Dir! :)
|
Re: Dynamische Arrays ... kleines Problem!
Kein Problem.
Streams sind zum verschieben von Datenmengen auf jeden Fall besser als file of-Konstruktionen. Es gibt übrigens auch ![]() ![]() |
Re: Dynamische Arrays ... kleines Problem!
Hmmm.. bekomme andauernd "undeclared Identifier" .... sehr merkwürdig, die sind doch definiert...
|
Re: Dynamische Arrays ... kleines Problem!
Zeig doch ein wenig Code.
Am besten den, in dem der Fehler auftritt |
Re: Dynamische Arrays ... kleines Problem!
Unter "Implementation" :
Delphi-Quellcode:
..muss hier kein record hin?(Hier habe ich garantiert noch etwas verwechselt) :oops:
Type
TSmallIntArray = Array of SmallInt; end; Ansonsten:
Delphi-Quellcode:
Procedure LoadTheWav: Identifier redeclared usw
(...)
procedure SaveWavFileClick(Sender: TObject); procedure DisableItems(Status: Boolean); procedure KeyNoteClickCheck(Sender: TObject); Procedure LoadTheWave(FileName: String; out Value: TSmallIntArray; Start: Integer = 0); private { Private declarations } public KeysToRecord: Array[0..11] of Integer; function ValidateInput(Itemobject: String; minval, maxval: Integer): String; { Public declarations } end; (...) :| |
Re: Dynamische Arrays ... kleines Problem!
1. der type muss ins interface, nicht in implementation
2. es sollte in ein EINER unit nur EINMAL type geben ! alles andere führt potenziell zu schlimmen Sachen.... 3. identifier redeclared kommt, weil du es im implementation abschnitt deklarierst, im interface aber schon verwedest... ja, die fehlermeldung ist ein wenig irreführend... |
Re: Dynamische Arrays ... kleines Problem!
Vielen Dank!! :)
EDIT: Hab es :oops: :lol: |
Re: Dynamische Arrays ... kleines Problem!
Okayyyy.... alllso einmal muss ich doch noch was fragen! :oops:
Und zwar:
Delphi-Quellcode:
Siehe "ProcessWave(FileName: String);"
Procedure TForm1.LoadTheWave(FileName: String; out Value: TSmallIntArray;Start: Integer = 0);
begin with TFilestream.Create(Filename, fmOpenRead) do try Position := Size; setlength(Value, Size-Position); ReadBuffer(Value,length(Value)); finally Free; end; end; Procedure TForm1.SaveTheWave(Filename: string; Value: TSmallIntArray); begin with TFileStream.Create(Filename, fmOpenWrite) do try WriteBuffer(Value,length(Value)*sizeof(SmallInt)); finally Free; end; end; Procedure TForm1.ProcessWave(FileName: String); var Wavbuffer: TSmallIntArray; Header: TWaveHeader; i: Integer; begin LoadTheWave(Outputfile.Text, Wavbuffer, sizeof(Header)+1); //laden des waves for i := 0 to high(Wavbuffer) do // testweise stille einfügen begin Wavbuffer[i] := 0; end; SaveTheWave(Outputfile.Text, Wavbuffer); end; Ich lade also das wav-file, modifiziere es und speichere es wieder ... allerdings hat sich rein gar nichts im WAV file verändert? :) |
Re: Dynamische Arrays ... kleines Problem!
Zitat:
Wenn du 0 Byte zu schreiben hast, nun ja, dann wird natürlich auch nie irgendwas geschrieben... Gruß Der Unwissende [EDIT] PS: Du solltest deine FileStreams noch etwas anders öffnen. Wenn du etwas zum Lesen öffnest, solltest du eine Schreibsperre setzen (sonst könntest du irgendwann das Problem haben, dass jmd. schreibt während du liest) und wenn du schreibst, dann kannst du gleich exklusiv sperren.
Delphi-Quellcode:
[/EDIT]
// zum Lesen:
TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); // zum Schreiben: TFileStream.Create(FileName, fmOpenRead or fmShareExclusive); |
Re: Dynamische Arrays ... kleines Problem!
Danke! Aber wieso ein "or" dazwischen? Nicht: fmOpenRead, fmSowieso?
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz