Forum: PC-Programmierung Speicher-Zuweisung bei C-Bibliotheksfunktionen mit Zeigern


von Rentner O. (rentner323)


Lesenswert?

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?

von Dr. Sommer (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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?

von Rentner O. (rentner323)


Lesenswert?

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.

von thestrangler (Gast)


Lesenswert?

---
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.

von Rentner O. (rentner323)


Lesenswert?

Yeah! Danke!

Wo hast du das gefunden (link)?

von thestrangler (Gast)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.