2017-02-09 4 views
-1

Ich habe gerade angefangen zu programmieren und habe eine Anfängerfrage. Ich habe also einen Binärbaum. Nachdem ich den ersten Knoten hinzugefügt habe, möchte ich den Baum durchsuchen, um zu sehen, ob es einen duplizierten Knoten mit demselben Wert gibt. Aber ich halte Fehler bekommen, wenn ich versuche, den Baum zu suchen, die nur einen Knoten hat: Hier ist mein Knoten:C Programmierung Heap Pufferüberlauf

struct node{ 
int data; 
struct node* left; 
struct node* right;}; 

Hier ist die Funktion, die ich verwendet, um den ersten Knoten

struct node* createnode(int num){ 
struct node *p=malloc(sizeof(struct node*)); 
p->data=num; 
return p; 
} 

Und ich zu erstellen Es ist wie diese hinzugefügt:

struct node *root; 
root=createnode(b); 

Hier ist die Suchfunktion

Hier

ist der Fehler, den ich bekam

==6841== ERROR: AddressSanitizer: heap-buffer-overflow on address  0x60040000e000 at pc 0x400eb5 bp 0x7fff3d5302c0 sp 0x7fff3d5302b0 
READ of size 8 at 0x60040000e000 thread T0 
#0 0x400eb4 (/.autofs/ilab/ilab_users/xy139/night+0x400eb4) 
#1 0x402911 (/.autofs/ilab/ilab_users/xy139/night+0x402911) 
#2 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14) 
#3 0x400a78 (/.autofs/ilab/ilab_users/xy139/night+0x400a78) 
0x60040000e000 is located 8 bytes to the right of 8-byte region [0x60040000dff0,0x60040000dff8) 
allocated by thread T0 here: 
#0 0x7f2196e74129 (/usr/lib64/libasan.so.0.0.0+0x16129) 
#1 0x402071 (/.autofs/ilab/ilab_users/xy139/night+0x402071) 
#2 0x402899 (/.autofs/ilab/ilab_users/xy139/night+0x402899) 
#3 0x7f2196abdb14 (/usr/lib64/libc-2.17.so+0x21b14) 
Shadow bytes around the buggy address: 
0x0c00ffff9bb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9bc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9bd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9be0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9bf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa 00 fa 
=>0x0c00ffff9c00:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9c10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9c20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9c30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9c40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
0x0c00ffff9c50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 
Shadow byte legend (one shadow byte represents 8 application bytes): 
Addressable:   00 
Partially addressable: 01 02 03 04 05 06 07 
Heap left redzone:  fa 
Heap righ redzone:  fb 
Freed Heap region:  fd 
Stack left redzone: f1 
Stack mid redzone:  f2 
Stack right redzone: f3 
Stack partial redzone: f4 
Stack after return: f5 
Stack use after scope: f8 
Global redzone:  f9 
Global init order:  f6 
Poisoned by user:  f7 
ASan internal:   fe 
==6841== ABORTING 

ich allen danken, die bereit sind zu helfen !!!!

+0

Vergessen Sie nicht, die beiden Zeiger in der Knotenerstellungsfunktion auf null zu setzen. –

+2

Bitte den Code einrücken. –

Antwort

2
struct node *p = malloc(sizeof(struct node*)); 

Sie müssen genügend Speicher für die Struktur selbst zuweisen, kein Zeiger auf struct.

struct node *p = malloc(sizeof(struct node)); 

Es ist einfacher, sich daran zu erinnern, dies zu tun, wenn Sie die Zielzeiger de-reference und übergeben ihre Größe zu malloc als Argument wie folgt:

struct node *p = malloc(sizeof(*p)); 

Wenn Sie den Datentyp ändern waren von p in einer späteren Revision eines Programms, dann müssten Sie die entsprechenden Argumente nicht auf malloc aktualisieren.

+1

OMG vielen Dank soooo, es hat funktioniert! Ich kann nicht glauben, dass die Aufgabe, an der ich ein paar Tage verbracht habe, fast durch so einen kleinen Fehler verloren gegangen wäre, Danke! – woshidashen

+0

Kein Problem. Ich bin froh, dass ich helfen kann. – synchronizer

0

Einer der typischen Fehler ist die Zuweisung des Speichers nicht für die Größe der Struktur, sondern für den Zeiger darauf. Synchronizer die solution des Problems in seiner Antwort zeigte:

struct node *p = malloc(sizeof(struct node)); 

ich auch hinzufügen soll, dass malloc einen möglicherweise Null-Zeiger zurückgeben kann (link), das ist, warum nach der Zuweisung von Speicher gegen Null vor dereferenzieren geprüft werden soll:

struct node* createnode(int num) 
{ 
    struct node *p = malloc(sizeof(struct node)); 
    if (p != NULL)        // <= 
    { 
    p->data = num; 
    } 
    return p; 
} 

Es ist so schade, dass es so lange gedauert hat, den Fehler zu finden. Vielleicht könnte die Verwendung von statischen Analysatoren dazu beitragen, Fehler früher zu finden. Here können Sie sehen, wie ein ähnlicher Fehler in großen Projekten gemacht werden kann.

+0

Hallo, vielen Dank für die durchgehende Antwort, die wirklich hilfreich ist! Ich frage mich, ob die Malloc-Funktion möglicherweise einen Null-Zeiger zurückgibt, wie kann ich einen Knoten erstellen und seinen Daten einen bestimmten Wert hinzufügen, wenn der Zeiger Null ist? Wenn ich Speicher für den von mir definierten Knoten reserviere, sollte der Speicher all die Dinge enthalten, die ich für diesen Knoten definiert habe? – woshidashen

+0

Das 'malloc' gibt nur unter ungünstigen Umständen einen Nullzeiger zurück. Diese Situation kann im Falle von fehlendem Speicher auftreten, oder vielleicht ist der Speicher zu fragmentiert, und Sie können keinen linearen Speicherblock erhalten.Daher ist es wichtig, den Zeiger nach der Speicherzuweisung zu überprüfen, da die Nullzeiger-Dereferenzierung zu [undefiniertem Verhalten] führt (http://en.cppreference.com/w/cpp/language/ub). Wenn der Speicher zugewiesen wurde (die Größe des "Knoten" in Ihrem Fall), werden nach dem Übertragen des "void" -Zeigers auf den "node" -Zeiger alle Strukturfelder für die Arbeit verfügbar sein. –

+0

Verstanden, Danke! – woshidashen