Speicher-Zuweisung bei C-Bibliotheksfunktionen mit Zeigern

OP #3776286
Hallihallo,

ich bin mir hier bei ner total trivialen Sache völlig unsicher:

Ich benutzt eine fremde C Bibliothek (pcap) in einem C++ Programm (Qt).

Dort gibt es folgende Funktion:
1
int pcap_next_ex  ( pcap_t *  p,  
2
  struct pcap_pkthdr **  pkt_header,  
3
  const u_char **  pkt_data   
4
 )

Jetzt übergebe ich der Funktion einen Pointer den ich vorher anlege:
1
u_char *pkt_data;

Jetzt die frage:
Wie funktioniert in dem Fall die Speicher Zuweisung -> kurz gesagt, muss 
ich den Buffer nach Benutzung wieder löschen?

In dem speziellen Fall beziehe ich mich auf folgendes Beispiel:
1
int main()
2
{
3
pcap_if_t *alldevs;
4
pcap_if_t *d;
5
int inum;
6
int i=0;
7
pcap_t *adhandle;
8
int res;
9
char errbuf[PCAP_ERRBUF_SIZE];
10
struct tm ltime;
11
char timestr[16];
12
struct pcap_pkthdr *header;
13
const u_char *pkt_data;
14
time_t local_tv_sec;
15

16
    
17
    //... 
18

19
    
20
    /* Retrieve the packets */
21
    while((res = pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
22
        
23
        if(res == 0)
24
            /* Timeout elapsed */
25
            continue;
26
        
27
        /* convert the timestamp to readable format */
28
        local_tv_sec = header->ts.tv_sec;
29
        localtime_s(&ltime, &local_tv_sec);
30
        strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);
31
        
32
        printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
33
    }
34
    
35
    if(res == -1){
36
        printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
37
        return -1;
38
    }
39
    
40
    return 0;
41
}
Hier mal am Beispiel vom "struct ... *header":
Am Anfang lege ich ja nur einen Zeiger an, dieser wird dann durch die 
Funktion pcap_next_ex aufgefüllt.
Wenn ich nun das Ende der Funktion erreiche, dann wird doch nur der 
Zeiger automatisch gelöscht. Müsste ich nicht das Object explizit aus 
dem Speicher löschen?
Gast #3776302
Rentner Opa schrieb:
> Wenn ich nun das Ende der Funktion erreiche, dann wird doch nur der
> Zeiger automatisch gelöscht.
Richtig.
> Müsste ich nicht das Object explizit aus
> dem Speicher löschen?
Das hängt davon ab, was für ein Speicher das ist den pcap_next_ex dir da 
gibt. Die Dokumentation von pcap_next_ex sagt dir, ob du den wieder 
selber freigeben musst oder irgendein anderer Teil von libpcap das 
automatisch macht oder das ein Zeiger auf statischen Speicher ist der 
nicht freigegeben werden muss... Auf Verdacht würde ich aber mal sagen 
dass du das mit free() wieder löschen musst.
Persönliche Seite #3776304
Rentner Opa schrieb:
> Müsste ich nicht das Object explizit aus
> dem Speicher löschen?

Nicht unbedingt; es kann sein, daß die Funktion pcap_next_ex den Pointer 
auf einen Puffer setzt, der anderswo verwaltet wird, oder statisch 
angelegt ist.

Wenn die Funktion allerdings tatsächlich via malloc/calloc Speicher 
anfordert, und den Pointer darauf zeigen lässt (und keine eigene 
zusätzliche Speicherverwaltung mit irgendwelchen anderen Funktionen 
betrieben wird, die Du hier nicht erwähnt hast), dann muss in der Tat 
der Speicher "von Hand" wieder freigegeben werden.

Daß der Pointer selbst auf dem Stack liegt und mit dem Beenden Deiner 
Funktion seine Gültigkeit verliert, löscht, wie Du richtig annimmst, den 
Speicher nicht, auf den der Pointer zeigt.

Das wäre im ersten Falle (Pointer zeigt auf statischen Speicher) auch 
ein Problem, denn wie löscht man statischen Speicher?
OP #3776316
Auszug aus der Doku zu besagter Funktion:
Read a packet from an interface or from an offline capture.

This function is used to retrieve the next available packet, bypassing 
the callback method traditionally provided by libpcap.

pcap_next_ex fills the pkt_header and pkt_data parameters (see 
pcap_handler()) with the pointers to the header and to the data of the 
next captured packet.

The return value can be:
•1 if the packet has been read without problems
•0 if the timeout set with pcap_open_live() has elapsed. In this case 
pkt_header and pkt_data don't point to a valid packet
•-1 if an error occurred
•-2 if EOF was reached reading from an offline capture


Woher weiß ich denn wie intern die Speicherverwaltung funktioniert?

Das Problem wird bei anderen Funktionen sicherlich auch wieder 
auftreten.
Gast #3776340
---
pcap_next_ex() reads the next packet and returns a success/failure 
indication. If the packet was read without problems, the pointer pointed 
to by the pkt_header argument is set to point to the pcap_pkthdr struct 
for the packet, and the pointer pointed to by the pkt_data argument is 
set to point to the data in the packet.

The struct pcap_pkthdr and the packet data are not to be freed by the 
caller, and are not guaranteed to be valid after the next call to 
pcap_next_ex(), pcap_next(), pcap_loop(), or pcap_dispatch(); if the 
code needs them to remain valid, it must make a copy of them.
---

Du darfst den Speicher also nicht selbst freigeben.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.