Forum: PC-Programmierung "Zugriffsverletzung" - warum?


von LinuX007 (Gast)


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:
1
char *getenv(const char *str);

1
#include <stdio.h>
2
#include <stdlib.h>
3
4
5
6
void print_html_header(void) {
7
   printf("<html><head>\n");
8
   printf("<title>Test</title>\n");
9
   printf("</head><body><pre>\n");
10
}
11
/* Das Ende eines HTML-Dokuments */
12
void print_html_end(void) {
13
   printf("</pre></body></html>\n");
14
}
15
/* Damit überhaupt ein HTML-Dokument ausgegeben wird */
16
void print_header(void) {
17
   printf("Content-Type: text/html\n\n");
18
}
19
int main(void) {
20
   char *temp;
21
   char *p;
22
   print_header();
23
   print_html_header();
24
   p = getenv("HTTP_USER_AGENT");
25
   temp =  getenv("QUERY_STRING");
26
   if(p!=NULL)
27
      printf("<tr><td>Der String lautet: %d</td></tr>",*temp);
28
29
      if (*temp == 1)
30
        printf("<tr><td>Ist eins!</td></tr>");
31
      else
32
        printf("<tr><td>Nicht eins!</td></tr>");
33
   print_html_end();
34
35
   return EXIT_SUCCESS;
36
}


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

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

Vielen Dank!

von Haku (Gast)


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?

von Sebastian C. (basti79)


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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Compiler meldet eine Zugriffsverletzung?!

Vermutlich nicht. Dennoch ist in Deinem Code vieles ziemlicher Quark, 
hiermit fängt es an:
1
   temp =  getenv("QUERY_STRING");
2
   if(p!=NULL)
3
      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:
1
      if (*temp == 1)
Auch hier: temp ist ein Pointer auf char!

Probier mal das hier aus:
1
int main(void) 
2
{
3
   char *temp;
4
   char *p;
5
   print_header();
6
   print_html_header();
7
   p = getenv("HTTP_USER_AGENT");
8
   temp =  getenv("QUERY_STRING");
9
   if (p)
10
      printf("<tr><td>Der eine String lautet: %s</td></tr>", p);
11
12
   if (temp)
13
   {
14
      printf("<tr><td>Der andere String lautet: %s</td></tr>", temp);
15
16
      if (atoi(temp) == 1)
17
        printf("<tr><td>Ist eins!</td></tr>");
18
      else
19
        printf("<tr><td>Nicht eins!</td></tr>");
20
   }
21
   print_html_end();
22
23
   return EXIT_SUCCESS;
24
}

von Tim (Gast)


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.

von Daniel (Gast)


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

von LinuX007 (Gast)


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!

von Tim (Gast)


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.

von LinuX007 (Gast)


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!

von Frank L. (florenzen)


Lesenswert?

argc

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.