2016-03-20 20 views
0

Ich bekomme den folgenden Fehler beim Freigeben von "shifted_text" unten. Ich habe mit print-Anweisungen überprüft und kommentiert, und es ist definitiv so frei (shifted_text). Die anderen freien Befehle funktionieren gut.C Heap-Puffer-Beschädigung bei Verwendung von free()

Debugfehler! HEAP CORRUPTION DETECTED: Nach normalem Block (# 77) bei 0x007D1F ...

CRT erkannt, dass die Anwendung nach Ende des Heap-Puffers in den Speicher geschrieben hat.

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

void parse(int argc, char *argv[]); 
char * shift_text(char *sometext); 
char shift_letter(char letter, char shift); 
void bring_in_text(void); 
void write_to_file(char *sometext); 

char *flag; 
char *password; 
char *text; 

int main(int argc, char *argv[]) 
{ 
    parse(argc, argv); 
    char *shifted_text; 
    // at this point flag can only be -e, -d, -df, -ef 
    if (strcmp(flag, "-e") == 0 || strcmp(flag, "-d") == 0) 
    { 
     // location to store the shifted text 
     shifted_text = (char*)malloc(strlen(text) * sizeof(char)); 
     shift_text(shifted_text); 
     printf("%s\n", shifted_text); 
    } 
    else 
    { 
     bring_in_text(); 
     // location to store the shifted text 
     shifted_text = (char*)malloc(strlen(text) * sizeof(char)); 
     shift_text(shifted_text); 
     write_to_file(shifted_text); 
    } 
    free(shifted_text); 
    free(text); 
    free(flag); 
    free(password); 
    return 0; 
} 

void write_to_file(char *sometext) 
{ 
    if (strcmp(flag, "-df") == 0) 
    { 
     FILE *fp; 
     fp = fopen("plaintext.txt", "w"); 
     if (fp == NULL) 
     { 
      puts("Unable to open file"); 
      exit(1); 
     } 
     fprintf(fp, sometext); 
     fclose(fp); 
    } 
    else if (strcmp(flag, "-ef") == 0) 
    { 
     FILE *fp; 
     fp = fopen("ciphertext.txt", "w"); 
     if (fp == NULL) 
     { 
      puts("Unable to open file"); 
      exit(1); 
     } 

     fprintf(fp, sometext); 
     fclose(fp); 
    } 
} 

void bring_in_text(void) 
{ 
    if (strcmp(flag, "-df") == 0) 
    {  
     FILE *fp; 
     fp = fopen("ciphertext.txt", "r"); 
     if (fp == NULL) 
     { 
      puts("Unable to open file"); 
      exit(1); 
     } 
     while (!feof(fp)) 
     { 
      text = (char*)malloc(100 * sizeof(char)); 
      fgets(text, 100, fp); 
     } 
     fclose(fp); 
    } 
    else if (strcmp(flag, "-ef") == 0) 
    { 
     FILE *fp; 
     fp = fopen("plaintext.txt", "r"); 
     if (fp == NULL) 
     { 
      puts("Unable to open file"); 
      exit(1); 
     } 
     while (!feof(fp)) 
     { 
      text = (char*)malloc(100 * sizeof(char)); 
      fgets(text, 100, fp); 
     } 
     fclose(fp); 
    } 

} 


char * shift_text(char *shifted_text) 
{ 
    char *temptext; 
    temptext = text; 
    char *tempshiftedtext; 
    tempshiftedtext = shifted_text; 
    // space for 10 characters plus null 
    char *temppswd; 
    temppswd = password; 

    for (int i = 0; i < strlen(text); i++) 
    { 
     char a; 
     if (*temptext >= 97 && *temptext <= 122) 
     { 
      a = shift_letter(*(temptext + i), *(temppswd + (i % strlen(password)))); 
      *(tempshiftedtext + i) = a; 
     } 
     else 
      *(tempshiftedtext + i) = *(temptext + i); 
    } 
    *(tempshiftedtext + strlen(text)) = '\0'; 
} 

char shift_letter(char letter, char shift) 
{ 
    if (strcmp(flag, "-e") == 0 || strcmp(flag, "-ef") == 0) 
    { 
     letter = letter - 97; 
     shift = shift - 97; 
     int shifted_letter = letter + shift; 
     if (shifted_letter > 25) 
      shifted_letter %= 26; 
     shifted_letter += 97; 
     return (char)shifted_letter; 
    } 
    else if (strcmp(flag, "-d") == 0 || strcmp(flag, "-df") == 0) 
    { 
     int shifted_letter = letter - 97; 
     shift = shift - 97; 
     int letter = shifted_letter - shift; 

     letter %= 26; // mod seems to allow negative results, so if its still negative. add another val equal to modulus 
     if (letter < 0) 
      letter += 26; 
     letter += 97; 
     return (char)letter; 
    } 
} 

void parse(int argc, char *argv[]) 
{ 
    if (argc == 4) 
    { 
     // internally calls malloc on strlen(argv[i]) 
     flag = _strdup(argv[1]); 
     password = _strdup(argv[2]); 
     text = _strdup(argv[3]); 
     if (strlen(password) > 10) 
     { 
      puts("Password too long"); 
      exit(1); 
     } 
     else if (strcmp(flag, "-e") != 0 && strcmp(flag, "-d") != 0) 
     { 
      puts("Incorrect flag"); 
      exit(1); 
     } 
    } 
    else if (argc == 3) 
    { 
     // internally calls malloc on strlen(argv[i]) 
     flag = _strdup(argv[1]); 
     password = _strdup(argv[2]); 
     if (strlen(password) > 10) 
     { 
      puts("Password too long"); 
      exit(1); 
     } 
     else if (strcmp(flag, "-ef") != 0 && strcmp(flag, "-df") != 0) 
     { 
      puts("Incorrect flag"); 
      exit(1); 
     } 
    } 
    else 
    { 
     puts("Incorrect arguements"); 
     exit(1); 
    } 
} 

Die Funktionen parse speichert einfach Befehlszeilenargumente in den globalen. Die Verschiebefunktionen verschieben einen Buchstaben um eine Zahl. Um 2 verschobenes "A" wäre beispielsweise "C". Diese funktionieren gut und ohne das freie (shifted_text) funktioniert das Programm.

Ich bin neu in C so ist es wahrscheinlich etwas einfaches, aber ich kann es nicht sehen.

+1

Ohne zu sehen, was in der 'shift_text' Funktion passiert, wie können wir Ihnen helfen? – Jack

+4

Sie wissen, dass Zeichenfolgen in C ein zusätzliches Abschlusszeichen haben? So ist die tatsächliche Länge von z.B. 'text' in Ihrem Code ist' strlen (text) + 1'. –

+0

@Jack Ich habe aktualisiert, um den ganzen Code zu zeigen, danke –

Antwort

0

strdup Zuweisungen Strlen + 1 Zeichen und Sie nur Strlen Zeichen zuweisen. Wenn Sie am Ende des verschobenen Textes den Nullwert schreiben, überlaufen Sie den Puffer.

1

Ändern Sie diese

shifted_text = (char*)malloc(strlen(text) * sizeof(char)); 

zu

shifted_text = malloc((strlen(text) + 1) * sizeof(char)); // don't cast 

Ein C-String hat immer einen Null-Terminator, was das Ende der Zeichenfolge. Zum Beispiel wird "foo" als 'f', 'o', 'o', '\0' im Speicher gespeichert. So müssen Sie

Ich vermute, dass die Heap-Puffer-Korruption wird nicht durch Ihre free(shifted_text); verursacht. Da nicht genügend Speicher shifted_text zugeordnet ist, wird ein undefiniertes Verhalten aufgerufen, was alles möglich macht. So kann Ihr Programm entweder ordnungsgemäß ausgeführt werden oder abstürzen. Vielleicht ist es nur ein Zufall, dass jedes Mal, wenn free(shifted_text); auskommentiert ist, Ihr Programm dank des undefinierten Verhaltens korrekt läuft.


BTW: Es gibt viele Stellen in Ihrem Code zu verfeinern. Zum Beispiel in void bring_in_text(void):

while (!feof(fp)) 
{ 
    text = (char*)malloc(100 * sizeof(char)); 
    fgets(text, 100, fp); 
} 

die bisherigen Linien Abdeckung, ohne sie selbst zu verarbeiten? Außerdem wird in dieser Funktion text nicht freigegeben.