2016-03-26 5 views
-3

Ausnahmebedingung bei 0x003165F0 in tStack.exe: 0xC0000005: Zugriffsverletzungsleseposition 0x9BFF07EF.?Ausnahmebedingung bei 0x003165F0 in tStack.exe: 0xC0000005: Zugriffsverletzungsleseort 0x9BFF07EF.?

Ich kann nicht scheinen, das Problem in diesem Programm festzunageln. Ich bekomme Lese-/Schreibfehler wie diese an verschiedenen Stellen. Hier ist die CPP und .h

CPP:

#include <stdio.h> 
#include <stdlib.h> 
#include "stack.h" 
#include <string> 
#include <iostream> 
//using namespace std; 

tStack::tStack() 
{ 
} 

tStack::~tStack() 
{ 
} 

tStack::tStack(const tStack &) 
{ 
} 

void tStack::Pop() 
{ 
    snode *tmp_ptr = NULL; 

    if (front) 
    { 

     tmp_ptr->next = front; 
     front = tmp_ptr; 
     free(tmp_ptr); 
    } 
    else 
     std::cout << "\nStack is Empty"; 
} 

void tStack::Push(std::string op) 
{ 
    snode *tmp_ptr = front; 

    tmp_ptr->data = op; 

    if (front) 
    { 
    tmp_ptr->next = front; 
    front = tmp_ptr; 
    } 
    else 
    { 
    front = tmp_ptr; 
    front->next = NULL; 
    } 
} 

void tStack::Print() 
{ 
    snode *cur_ptr = front; 

    if (cur_ptr) 
    { 
     std::cout << "\nElements in Stack:\n"; 
     while (cur_ptr) 
     { 
      std::cout << cur_ptr->data; 
      cur_ptr = cur_ptr->next; 
     } 
     std::cout << "\n"; 
    } 
    else 
     std::cout << "\nStack is Empty"; 
} 

void tStack::cStack() 
{ 
    free(front); 
} 

void tStack::convert(std::string postfix, tStack a) 
{ 
    int count = 0; 
    bool lastOper; 
    std::string pusher, val1, val2; 

    for (int i = 0; i < postfix.size(); i++) 
    { 
     if (isalpha(postfix[i])) 
     { 
      pusher = postfix[i]; 
      a.Push(pusher); 
      count++; 

     } 
     else 
     { 

      if (count < 2) 
      { 
       std::cout << "There are not enough values to perform an operation."; 
      } 

      else 
      { 
       pusher = postfix[i]; 
       val1 = front->data; 
       a.Pop(); 
       val2 = front->data; 
       a.Pop(); 
       a.Push(")"); 
       a.Push(val1); 
       a.Push(pusher); 
       a.Push(val2); 
       a.Push("("); 
      } 
      lastOper = true; 
     } 
    } 
} 

.h:

#pragma once 
#include <stdio.h> 
#include <stdlib.h> 
#include "stack.h" 
#include <string.h> 
#include <iostream> 
//using namespace std; 
class snode 
{ 
public: 
    std::string data; 
    snode *next; 
}; 
class tStack 
{ 
public: 
    tStack(); 
    ~tStack(); 
    tStack(const tStack &); 
    void Pop(); 
    void Push(std::string); 
    void Print(); 
    void cStack(); 
    void convert(std::string, tStack); 
private: 

    snode *front; 


}; 

ich einige Einträge gefunden was darauf hindeutet, nicht using namespace std verwenden, aber das scheint nicht zu helfen, . Habe ich nur ein totales Missverständnis darüber, wie verknüpfte Listen funktionieren?

+1

Ihre Zeiger Mathe irgendwo ausgeschaltet ist. Sie müssen Ihr Programm debuggen, um herauszufinden, wo. – Carcigenicate

+0

Danke, könntest du etwas für mich klären? Wenn ich sage Front-> next = temp_ptr; Habe ich Recht, wenn ich bedenke, dass der nächste Zeigerwert der Front nun darauf zeigt, auf was temp_ptr zeigt? – Perkis

+0

Es sieht aus wie jemand anderes das Problem bereits gefunden hat. Wenn Sie jedoch einen Zugriffsverletzungsfehler erhalten, bedeutet das normalerweise, dass Sie eine Adresse falsch berechnen oder Ihren Speicher schlecht verwalten. Und es tut mir leid, es ist lange her, seit ich mich mit Zeigern beschäftigt habe, ich will dich nicht in die Irre führen. – Carcigenicate

Antwort

0

Der erste Blick auf Ihren Code und ich habe einen Fehler entdeckt.

front = tmp_ptr; 
free(tmp_ptr); 

Dieser Code macht keinen Sinn. Sie haben tatsächlich Speicher frei, der oben auf Ihrem Stack verwendet wird. Die Behebung solcher Fehler sollte einfach sein.

+0

Vielen Dank. Beziehen Sie sich nur auf die freie Methode oder front = tmp_ptr; auch? – Perkis

+0

@Perkis nur frei, sollten Sie sich erinnern, alte Front und frei – greenshade

0

Mit Blick auf Ihren Code würde ich davon ausgehen, dass Sie versuchen, Ihre hausgemachte verknüpfte Liste in einer "Stapel" -Methode zu implementieren (erste, letzte und umgekehrt); lass es mich wissen, wenn ich falsch liege.

Ich kann ein paar Probleme mit Ihrem Code sehen:

Problem 1: In Ihrem „Pop“ Methode Sie versuchen die „Front“ Mitglied zu verwenden, ohne die Versicherung, dass es NULL ist, wenn das Verfahren läuft das erste Mal; Fügen Sie eine Definition dafür im Standardkonstruktor von "tStack" hinzu, der NULL zuweist.

Problem 2: Ich glaube, dass Sie Ihre "Pop" -Methode Elemente aus der Liste entfernen möchten, nicht hinzufügen. Hab ich recht? Wenn ja, dann ist Ihre "Pop" -Methode falsch implementiert. Hier ist eine richtig geschrieben Version Ihres „Pop“ Methode:

void tStack::Pop() 
{ 
    if (front) 
    { 
     snode *tmp_ptr = front; 

     front = front->next; 


     free(tmp_ptr); 
    } 
    else 
     std::cout << "\nStack is Empty"; 
} 

Hinweis: I implementiert diese Methode in einer Weise, dass Ihre Liste als „Stack“ behandelt.

Dieser Code bringt ein anderes wichtiges Thema, Sie sollten einen Standardkonstruktor für Ihre "snode" -Klasse definieren, so dass er automatisch seinem "nächsten" Mitglied NULL zuweist.

Problem 3: Ihre "Push" -Methode ist nicht korrekt implementiert. "tmp_ptr" sollte neuen Speicher zugewiesen werden, nicht das erste Element der Liste.

Die Linie:

snode *tmp_ptr = front; 

sollte sein:

snode *tmp_ptr = new snode; 

Hinweis:

void tStack::Push(std::string op) 
{ 
    snode *tmp_ptr = new snode; 

    tmp_ptr->data = op; 

    tmp_ptr->next = front; 

    front = tmp_ptr; 
} 

Hinweis: Sie können dies Ihr "Push" -Verfahren verkürzen, indem Sie: Dieser Code setzt voraus, dass t er "snode" s "next" -Elemente werden immer gleich NULL sein, wenn kein nachfolgendes Element vorhanden ist. Dies ist ein Grund, warum es für Sie gut wäre, einen benutzerdefinierten Standardkonstruktor für Ihre "snode" -Klasse zu implementieren.

Problem 4: Die "cStack" -Methode sollte jedes Element Ihrer Liste durchlaufen und jedes einzeln freigeben. Die aktuelle Implementierung, die Sie jetzt haben, befreit nur das erste Element.

Hinweis: Jede Klasse, die Zeiger auf dynamisch Speicher enthalten zugewiesen, dass es besitzt, tun könnte eine benutzerdefinierte destructor haben, die den dynamischen Speicher löscht, dass sie zugewiesen hat. Dies gilt auch dann, wenn eine Methode verwendet wird, um den dynamischen Speicher von einer externen Quelle zu löschen, da ein Backup-Plan immer gut ist.

Dieser Hinweis gilt jedoch nicht für Ihre "snode" -Klasse (zumindest nicht für das "nächste" Mitglied), da das Löschen eines Elements Ihrer Liste eine Kettenreaktion auslösen würde, die gelöscht würde alle folgenden Elemente.

Nun, das sind alle Probleme, die ich sehen kann. Lassen Sie mich wissen, ob meine Antwort geholfen hat. :)

EDIT: Ihre "TStack" Klasse hat einen leeren Standardkonstruktor:

tStack::tStack() 
{ 
} 

ändern es dazu:

tStack::tStack() 
: front(NULL) 
{ 
} 

Ihr Standard destructor ist dies:

tStack::~tStack() 
{ 
} 

Ändern Sie diese Einstellung wie folgt:

tStack::~tStack() 
{ 
    // Clear the dynamic memory if needed. 
    if (front) 
     cStack(); 
} 

schließlich einen Standardkonstruktor zu Ihrem „snode“ Klasse hinzufügen:

snode::snode() 
: next(NULL) 
{ 
} 
+0

WOAH. Vielen Dank! Du hast meine Fragen beantwortet und dann einige! – Perkis

+0

Soweit Konstrukteure und Destruktoren gehen, lerne ich immer noch. Kennen Sie irgendwelche Ressourcen, die mir helfen könnten, einen richtigen Konstruktor und Destruktor für verknüpfte Listen zu schreiben? Ich habe jetzt eine Reihe von Lecks, so scheint es. Weißt du auch, wie ich ein b + gleich wie ab + behandelt bekommen könnte? – Perkis

+0

Mit "Ressourcen" meinen Sie Ressourcen für verknüpfte Listen speziell oder nur für Konstruktoren/Destruktoren im Allgemeinen? Sag mir, wie viel weißt du über Konstruktoren/Destruktoren? Haben Sie diesen Standardkonstruktor selbst in Ihren Code eingefügt, oder haben Sie ihn kopiert und von jemand anderem eingefügt? Ich frage nur, weil ich Ihnen einen Konstruktor und Destruktor geben kann, der in ein paar Zeilen Code funktioniert, aber ich möchte sicherstellen, dass Sie verstehen, was ich Ihnen sage. Kannst du ein wenig über deine zweite Frage nachdenken? Ich bin mir nicht sicher, was du meinst. : \ – Fearnbuster