2017-09-30 8 views
0

vignere暗号のcでプログラムを書いていましたが、同じ長さのキーを生成する関数で、入力文字列の長さを表示する "printf"行を削除すると、sceenに奇妙なものが表示されますが、GenKey()関数からその "printf"行を削除した場合にのみ発生します。 (その行を削除する前に)C:プログラムがchar関数からprintfを削除した後、出力に奇妙なものを出力する

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

char *GenKey(char *key, char *source){ 
    int i=0,j=0; 
    char ReturnKey[strlen(source)]; 

    printf("%d\n",strlen(source));  // THIS LINE HERE CAUSES PROBLEM 

    for(i=0;i<strlen(source)-1;i++){ 
     if(j==strlen(key)){ 
      j=0; 
     } 
     ReturnKey[i]=key[j]; 
     j++; 
     } 
     return ReturnKey; 
} 

int main() 
{ 
    int i; 
    char name[10000]; 
    char container[10000]; 
    char VigKey[]="INFERNO"; 
    char *NamePtr; 
    char *KeyPtr; 
    printf("give a name: "); 
    fgets(name,10000,stdin); 

    char GeneratedKey[strlen(name)]; 
    KeyPtr=VigKey; 
    NamePtr=name; 
    strcpy(GeneratedKey,GenKey(KeyPtr,NamePtr)); 
    printf("%s",GeneratedKey); 
} 

出力:

give a name: ATTACKATDAWN 
13 
INFERNOINFER 

今私は、その行を削除します(その行を削除した後)

char *GenKey(char *key, char *source){ 
    int i=0,j=0; 
    char ReturnKey[strlen(source)]; 

    // NOW I HAVE DELETED THAT LINE 

    for(i=0;i<strlen(source)-1;i++){ 
     if(j==strlen(key)){ 
      j=0; 
     } 
     ReturnKey[i]=key[j]; 
     j++; 
     } 
     return ReturnKey; 
} 

出力:

give a name: ATTACKATDAWN 
INFERNOINFERα╫` 
+0

あなたはメモリへのポインタを返すしていますすでにリリースされています。関数が返された後、自動ローカル変数はもう存在しません。 – zerkms

+0

コンパイラ警告をオンにします。 –

答えて

1

てみてくださいReturnKey文字配列をあなたが唯一のその関数のコンテキストに住んでいるローカル変数ようにやっていた、ReturnKeyを作成した時に前

char *GenKey(char *key, char *source){ 
    int i=0,j=0; 
    char *ReturnKey = malloc(sizeof(char) * strlen(source)); 
    for(i=0;i<strlen(source)-1;i++){ 
     if(j==strlen(key)){ 
      j=0; 
     } 
     ReturnKey[i]=key[j]; 
     j++; 
    } 
    return ReturnKey; 
} 

:このようなmalloc関数とヒープ。あなたの言葉がまだそこに残っているとは言えますが、それは単にそれがメモリ上のその位置にありますが、もはやオブジェクトによって参照されていなかったからです。

mallocのような関数を使って動的配列を作成すると、スコープから外れたときに解放されないいわゆる "ヒープ"上に作成されます。このようにして関数から戻すことができます実際にはメモリ内のその場所へのポインタを返します)。

メモリが解放されていないことに注意してmallocを使用すると、後でいつでもfreeを呼び出して解放する必要があります。そうしないとメモリがリークします。

これは完全なコードがどのように見えるかです:ここでは

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

char *GenKey(char *key, char *source){ 
    int i=0, j=0; 

    // malloc takes the size of the data type * the length 
    char *ReturnKey = malloc(sizeof(char) * strlen(source)); 

    for(i=0;i<strlen(source)-1;i++){ 
     if(j==strlen(key)){ 
      j=0; 
     } 
     ReturnKey[i]=key[j]; 
     j++; 
    } 
    return ReturnKey; 
} 

int main() 
{ 
    int i; 
    char name[10000]; 
    char container[10000]; 
    char VigKey[]="INFERNO"; 
    char *NamePtr; 
    char *KeyPtr; 
    printf("give a name: "); 
    fgets(name,10000,stdin); 

    KeyPtr=VigKey; 
    NamePtr=name; 
    char *GeneratedKey = GenKey(KeyPtr,NamePtr); 
    printf("%s",GeneratedKey); 
    free(GeneratedKey); // IMPORTANT!!! 
} 

はmallocとfreeを使用してのより深い記事です:

https://www.codingunit.com/c-tutorial-the-functions-malloc-and-free

+0

この回答は、元のコードに何が問題なのか、そして変更によってどのように修正されたのかを説明してくれれば本当に役に立ちます。それがなければ、このアドバイスは誰の助けにもなりません(効果的にOPアプリケーションのメモリリークになります)。 – zerkms

+0

@zerkmsよ、あなたの右は私に編集させてください – Asleepace

+0

............. – zerkms