www.mikrocontroller.net

Forum: PC-Programmierung "Zugriffsverletzung" - warum?


Autor: LinuX007 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Hier möchte ich mal eine Frage stellen, weshalb ich vom Compiler eine 
Fehlermeldung bekomme, da eine Zugriffsverletzung auftritt.
Es ist ein CGI-Skript, mit dem ich eine Umgebungsvariable des namens 
QUERY_STRING abfragen möchte.
Die Prototyp der Funktion getenv() sieht so aus:
char *getenv(const char *str);


#include <stdio.h>
#include <stdlib.h>



void print_html_header(void) {
   printf("<html><head>\n");
   printf("<title>Test</title>\n");
   printf("</head><body><pre>\n");
}
/* Das Ende eines HTML-Dokuments */
void print_html_end(void) {
   printf("</pre></body></html>\n");
}
/* Damit überhaupt ein HTML-Dokument ausgegeben wird */
void print_header(void) {
   printf("Content-Type: text/html\n\n");
}
int main(void) {
   char *temp;
   char *p;
   print_header();
   print_html_header();
   p = getenv("HTTP_USER_AGENT");
   temp =  getenv("QUERY_STRING");
   if(p!=NULL)
      printf("<tr><td>Der String lautet: %d</td></tr>",*temp);

      if (*temp == 1)
        printf("<tr><td>Ist eins!</td></tr>");
      else
        printf("<tr><td>Nicht eins!</td></tr>");
   print_html_end();

   return EXIT_SUCCESS;
}





Warum meldet der Compiler in der Zeile
 if (*temp == 1)

Ich möchte doch nur den Speicherinhalt der Adresse überprüfen, die in 
temp gespeichert ist.

Vielen Dank!

Autor: Haku (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler schmeißt da sicherlich keine Zugriffsverletzung, zumindest 
ein C-Compiler nicht. Das macht wenn schon dein Programm zur Laufzeit... 
ist denn QUERY_STRING überhaupt belegt oder geistert der temp-Zeiger 
in der Wildnis herum?

Autor: Sebastian C. (basti79)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo...

erstmal schaut es so aus, als wenn du hinter if(p!=NULL) die Klammer "{" 
vergessen hast. Zumindest wenn alles was eingerückt ist in dem IF-Block 
stehen soll.

Dann solltest du bevor du auf *temp zugreifst auch überprüfen ob temp != 
NULL ist, wenn temp nämlich NULL ist und du dann den Zugriff versucht 
kommt natürlich ein Speicherzugriffsfehler. Weiter ist die Frage was 
genau du mit *temp == 1 prüfen willst, wenn du wissen willst, ob das 
erste Zeichen des QUERY_STRING eine 1 ist dann müsste es wohl == '1' 
heißen.

Greets
  Sebastian.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler meldet eine Zugriffsverletzung?!

Vermutlich nicht. Dennoch ist in Deinem Code vieles ziemlicher Quark, 
hiermit fängt es an:
   temp =  getenv("QUERY_STRING");
   if(p!=NULL)
      printf("<tr><td>Der String lautet: %d</td></tr>",*temp);

temp ist ein Pointer auf char, Du dereferenzierst ihn und lässt printf
einen Integer erwarten.

Du überprüfst nicht, ob temp NULL ist, auch nicht bei der Zeile, bei 
der Deine Fehlermeldung auftritt:
      if (*temp == 1)
Auch hier: temp ist ein Pointer auf char!

Probier mal das hier aus:
int main(void) 
{
   char *temp;
   char *p;
   print_header();
   print_html_header();
   p = getenv("HTTP_USER_AGENT");
   temp =  getenv("QUERY_STRING");
   if (p)
      printf("<tr><td>Der eine String lautet: %s</td></tr>", p);

   if (temp)
   {
      printf("<tr><td>Der andere String lautet: %s</td></tr>", temp);

      if (atoi(temp) == 1)
        printf("<tr><td>Ist eins!</td></tr>");
      else
        printf("<tr><td>Nicht eins!</td></tr>");
   }
   print_html_end();

   return EXIT_SUCCESS;
}

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal was anderes:
Warum programmierst du das nicht in einer Scriptsprache die genau für 
diese dynamischen Webanwendungen geschaffen wurde?

Zu empfehlen währe PHP oder Perl.
Damit kannst du dir vieles einfacher machen.

Ich programmiere selbst (u.a.) in C, PHP und Perl.
C würde Ich niemals für CGIs verwenden.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Linux007

dir fehlen paar Grundlagen^^
Zeiger zeigen erstmal auf gar nichts, wenn man sie anlegt.
Erst wenn du ihnen die Adresse eines bereits existierenden
Objektes gibst, erst dann kann man * vor ihnen schreiben!

Nimm dir besser Python, Perl oder Ruby
C ist was für Systemprogrammierung und/oder Mikrokontroller
.. naja und kleine Tools vielleicht noch.

grüsse

Autor: LinuX007 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja gut ich werde mich dann mal in Perl einlesen.

Der oben gezeigte Code funktioniert jedenfalls schon mal. Wie kann ich 
aber den zuletzt eingegebenen Parameter auf dem Server speichern, damit 
man von einem anderen PC beim Aufruf der CGI-Datei den Wert angezeigt 
bekommt?

Beispiel:

 Ich gebe den Parameter eine 1. Nun zeigt die Seite an "Ist eins!". Wenn 
ich nun von einem anderen PC aus die CGI-Datei öffne, soll dort stehen 
"ist eins!" und aktualisiert werden, sobald ein anderer Parameter 
übergeben wird.


Danke!

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du must die Daten irgendwie auf der HDD speichern.
Im einfachsten fall in einer simplen Datei.

Wenn du aber später mehr machen willst als nur
einsen durch die Gegend zu schieben solltest du
über die Verwendung einer Datenbank nachdenken.
Die Lernkurve ist zwar Steil, Lohnt sich aber.

Autor: LinuX007 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey :)

Vielen Dank für deine Antwort! Super Ansatz :-) werde ich heute oder 
morgen probieren :)


Aber....wie wird denn die cgi-Datei nur "geladen", ohne ihr einen 
Parameter zu übergeben?

Denn, wenn ich die Datei lediglich mit 
http://localhost/cgi-bin/tacho.cgi  aufrufe, dann erwartet die CGI doch 
einen Eingabeparameter (also das, was hinter dem "?" steht), oder?

Ich brauche also eine Routine, die überprüft, ob die Seite OHNE 
Übergabeparameter geöffnet wird (also OHNE fragezeichen hinter 
"tacho.cgi"). Wie mache ich das?


Danke!

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
argc

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.