AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Was haltet ihr von diesem Code?

Ein Thema von Olli73 · begonnen am 2. Jul 2024 · letzter Beitrag vom 3. Sep 2024
Antwort Antwort
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
702 Beiträge
 
#1

Was haltet ihr von diesem Code?

  Alt 2. Jul 2024, 11:39
Delphi-Quellcode:
const
  ANY_SIZE = 1;
  
type

  MIB_IPADDRROW = record
    dwAddr: LongInt;
    dwIndex: LongInt;
    dwMask: LongInt;
    dwBCastAddr: LongInt;
    dwReasmSize: LongInt;
    unused1: word;
    unused2: word;
  end;

  MIB_IPADDRTABLE = record
    dwNumEntries: LongInt;
    table: array [1 .. ANY_SIZE] of MIB_IPADDRROW;
  end;

  TMIBIpAddrTable = MIB_IPADDRTABLE;
  PMIBIpAddrTable = ^TMIBIpAddrTable;


function GetNetworkAdapters(out AAdapters: TNetworkAdapterInfos): Boolean;
var
  pIfTable: PMIBIfTable;
  pIpTable: PMIBIpAddrTable;
  ifTableSize, ipTableSize: LongInt;
  CurrentAdapter: TNetworkAdapterInfo;
  MacAddress: string;
  i, j, k: Integer;
  sAddr, sMask: in_addr;
  IPAddresses, IPMasks: TDictionary<Integer, AnsiString>;
  IPString: AnsiString;
begin
  IPAddresses := TDictionary<Integer, AnsiString>.Create;
  try
    IPMasks := TDictionary<Integer, AnsiString>.Create;
    try
      ipTableSize := SizeOf(TMIBIpAddrTable);
      GetMem(pIpTable, ipTableSize);
      if GetIpAddrTable(pIpTable, ipTableSize, False) = ERROR_INSUFFICIENT_BUFFER then
      begin
        FreeMem(pIpTable, SizeOf(TMIBIpAddrTable));
        GetMem(pIpTable, ipTableSize);
      end;
      try
        if GetIpAddrTable(pIpTable, ipTableSize, False) = NO_ERROR then
        begin
          for k := 1 to pIpTable^.dwNumEntries do
          begin
            sAddr.S_addr := pIpTable^.table[k].dwAddr;
            sMask.S_addr := pIpTable^.table[k].dwMask;
            if not IPAddresses.ContainsKey(pIpTable^.table[k].dwIndex) then
              IPAddresses.Add(pIpTable^.table[k].dwIndex, inet_ntoa(sAddr));
            if not IPMasks.ContainsKey(pIpTable^.table[k].dwIndex) then
              IPMasks.Add(pIpTable^.table[k].dwIndex, inet_ntoa(sMask));
          end;
        end;
      finally
        if Assigned(pIpTable) then
          FreeMem(pIpTable, ipTableSize);
      end;

...

end;
Hier wird ein Array [1..1] per Pointer und GetMem dazu missbraucht, mehr Daten aufzunehmen, als eigentlich in das Array passen. Da hat bei mir dann der RangeCheck zugeschlagen und ich musste diesen an der Stelle abschalten.

Aber macht man sowas wirklich?

Geändert von TBx ( 2. Jul 2024 um 14:18 Uhr) Grund: Titel korrigiert
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.425 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Was hatet ihr von diesem Code?

  Alt 2. Jul 2024, 11:53
Informatiker-Antwort: man schon, ein guter Entwickler nicht.

Und wenn wir schon dabei sind:
1. TDictionary<Integer, AnsiString>
a) 3x, dann besser Typ definieren. Am Besten mit einem Namen so dass man versteht was das soll.
b) AnsiString: macht man das heuzutage noch?
2. Methode zu lang
3. "Was hatet ihr von diesem Code?" Also haten muss man den Code nicht, es gibt wesentlich schlimmeres

Geändert von freimatz ( 2. Jul 2024 um 11:57 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.139 Beiträge
 
Delphi 10 Seattle Enterprise
 
#3

AW: Was hatet ihr von diesem Code?

  Alt 2. Jul 2024, 11:59
Ja, ich finde das auch schon zu verschachtelt und unübersichtlich, aber ich glaube das war gar nicht gemeint, sondern die Geschichte mit den ANY_SIZE-Array:
https://devblogs.microsoft.com/oldne...26-00/?p=38043

Zitat:
Also haten muss man den Code nicht, es gibt wesentlich schlimmeres
Doch, ich hate ihn jetzt schon.

Spätere/Neuere Methoden aus der WinApi haben es dann besser gemacht und z.B. eine LinkedList als Datenstruktur zurückgegeben:

https://learn.microsoft.com/en-us/wi...ptersaddresses

https://learn.microsoft.com/en-us/wi...r_addresses_lh

Geändert von Der schöne Günther ( 2. Jul 2024 um 12:03 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
702 Beiträge
 
#4

AW: Was hatet ihr von diesem Code?

  Alt 2. Jul 2024, 13:18
2. Methode zu lang
Also bei Methoden, die weniger als ein paar Tausend Zeilen haben, rege ich mich erst gar nicht mehr auf ...

Ist halt teilweise uralter Code von Anderen, ich muss halt damit zurechtkommen. Das Problem hier war, dass der RangeCheck (im Release war der bei dem Projekt deaktiviert) zugeschlagen hat und ich der Meinung bin, Pointer und GetMem sollte man in solchen Fällen vermeiden, sonst kann man gleich C++ machen.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Was hatet ihr von diesem Code?

  Alt 2. Jul 2024, 13:35
Seit ein paar Delphi-Versionen ist die Bereichsprüfung standardmäßig aktiv.
[0..0] oder [1..1] gibt es öfters, aber bei größerem Index knallen diese Prüfungen.

Tipp: [1 .. MaxInt div SizeOf(MIB_IPADDRROW)] of MIB_IPADDRROW;
Alternativ die Pointer-Arithmetic aktivieren
und anstatt PMIBIpAddrTable = ^TMIBIpAddrTable;
ein PMIBIpAddr = ^MIB_IPADDRROW; , welches sich auch via .table[k] zugreifen lässt.

Achtung, da beginnt es mit Index 0, also so als wäre es [0..x]

Und wenn 0, dann beim for k := 0 to pIpTable^.dwNumEntries - 1 do aufpassen, da dwNumEntries ein DWORD ist und es somit Probleme gibt, wenn dwNumEntries 0 wäre, da bei -1 dann 4 Millarden, anstatt -1 rauskommt.
OK, zum Glück ist heutzutage standfardmäßig die Überlaufprüfung aktiv und würde bei 0 - 1 schön knallen.

Also besser to Integer(pIpTable^.dwNumEntries) - 1 do (größer als 2 Milliarden wird dwNumEntries hoffentlich nie sein)
oder vorher ein if pIpTable^.dwNumEntries > 0 then for ... .
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 2. Jul 2024 um 13:43 Uhr)
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.457 Beiträge
 
Delphi 10.4 Sydney
 
#6

AW: Was haltet ihr von diesem Code?

  Alt 8. Jul 2024, 06:58
Speicher muss man erst für den zweiten Aufruf der Funktion reservieren:
Delphi-Quellcode:
...
      ipTableSize := 0;
      pIpTable := nil;
      if GetIpAddrTable(pIpTable, ipTableSize, False) = ERROR_INSUFFICIENT_BUFFER then
      begin
        GetMem(pIpTable, ipTableSize);
        try
          if GetIpAddrTable(pIpTable, ipTableSize, False) = NO_ERROR then
          begin
...
          end;
        finally
          FreeMem(pIpTable);
        end;
     end;
...
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
702 Beiträge
 
#7

AW: Was haltet ihr von diesem Code?

  Alt 8. Jul 2024, 07:10
Da das nur ein Pointer ist, der noch nicht auf einen Record zeigt, muss man doch Speicher reservieren!?
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Was haltet ihr von diesem Code?

  Alt 8. Jul 2024, 07:32
Es kommt drauf an.

Schau in die Hilfe.
MSDN-Library durchsuchenGetIpAddrTable

Es gibt API,
* die wollen vom Nutzer Speicher haben
* Vielen wollen Speicher bekommen, aber ihnen reicht z.B. eine Record-Variable
* * hier würde sie auch reichen, wenn es nur eine IP gibt (oder wenn man sich selbst den Typen anpasst und z.B. [0..9] für maximal 10 IPs)
* Andere geben einen Zeiger auf internen Speicher raus
* oder sie erzeugen selbst den Speicher, welchen man dann ebenfalls freigeben muß

Zitat:
Delphi-Quellcode:
type
  MIB_IPADDRROW = ...
Warum?

Du verwendest eine API, welche nicht nur einen billigen Pointer als Typ hat, und da ist es natürlich einfacher/besser, auch diesen Typen dann zu verwenden.
Sonst kann es auch schnell passieren, dass der Compiler abraucht, wenn es ihm nicht gefällt, dass es "unterschiedliche" Typen sind.

Winapi.IpHlpApi
Winapi.IpRtrMib

PS: Windows.NetworkManagement.IpHelper aus'm GetIt WinMD
https://www.delphipraxis.net/214473-...vor-winmd.html
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 8. Jul 2024 um 09:29 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
702 Beiträge
 
#9

AW: Was haltet ihr von diesem Code?

  Alt 8. Jul 2024, 08:08
Ja, aber in dem Fall will die API doch reservierten Speicher, und ein Pointer irgendwohin, schreibt halt auch "irgendwohin" oder crasht.

Außerdem ist der Code ja nicht von mir. Mir gefällt ja auch nicht, dass ich die Bereichsüberprüfung lokal abschalten musste.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.457 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Was haltet ihr von diesem Code?

  Alt 3. Sep 2024, 15:49
Die Funktion prüft erst ob ipTableSize genügend groß ist um die Ergebnisse aufzunehmen.
Bei 0 ist das nicht der Fall.
Deshalb gibt die Funktion in ipTableSize die tatsächlich benötigte Größe zurück und setzt Result auf ERROR_INSUFFICIENT_BUFFER.
Auf den Zeiger greift die Funktion in diesem Fall garnicht zu.
  Mit Zitat antworten Zitat
Antwort Antwort


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 01:12 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