2016-03-20 29 views
0

Aşağıdaki "shifted_text" 'i serbest bırakırken aşağıdaki hatayı alıyorum. Baskı ifadelerini kontrol ettim ve bazı şeyleri yorumladım ve kesinlikle bu kadar özgür (shifted_text). Diğer ücretsiz komutlar iyi çalışıyor.C Ücretsiz() kullanırken yığın arabelleği bozulması()

Hata Ayıklama Hatası! HEAP CORRUPTION ALGILANMASI: 0x007D1F ...

adresindeki normal bloktan (# 77) sonra, uygulamanın bellek arabelleğinin sona ermesinden sonra belleğe yazdığı tespit edildi.

#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); 
    } 
} 

İşlevler ayrıştırmak, yalnızca komut satırındaki argümanları global olarak depolar. Vardiyalı fonksiyonlar bir mektubu bir miktar değiştirir. Örneğin 2 ile değiştirilen 'A', 'C' olur. Bunlar iyi çalışır ve ücretsiz (shifted_text) program olmadan çalışır.

C için yeniyim, bu yüzden muhtemelen basit bir şey ama göremiyorum.

+1

'shift_text' işlevinin içinde neler olduğunu görmeden nasıl yardımcı olabiliriz? – Jack

+4

C'deki dizelerin fazladan bir sonlandırıcı karakteri olduğunu biliyor musunuz? Yani gerçek uzunluğu örn. Kodunuzdaki 'metin' strlen (metin) + 1'dir. –

+0

@Jack Bütün kodu göstermek için güncelledim, teşekkürler –

cevap

0

strdup strlen + 1 karakterlerini ayırır ve yalnızca strlen karakterleri ayırırsınız. Değiştirilen metnin sonunda null yazdığınızda, arabellek taşıyor.

1

Değişim bu

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

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

C-tarzı dize her zaman dize sonunu gösteren bir boşlukla terminatör sahiptir. Örneğin, "foo", bellekte 'f', 'o', 'o', '\0' olarak saklanır.

Bu nedenle, yığın arabelleği bozulmasının free(shifted_text); tarafından kaynaklandığından şüpheleniyorum. Yetersiz bellek shifted_text'a tahsis edildiğinden, tanımlanmamış bir davranış başlatılır ve bu da her şeyi mümkün kılar. Bu nedenle programınız düzgün çalışabilir veya çökebilir. Belki de, her zaman free(shifted_text);'un yorumlandığı bir rastlantıdır, programınız tanımsız davranış sayesinde doğru bir şekilde çalışır.


BTW: Kodunuzda rafine edilecek birçok yer var.

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

işlemeden bile olmadan önceki satırları kapsayan: void bring_in_text(void) Mesela? Ayrıca, bu işlevde text boş bırakılmaz.