2017-11-19 10 views
0

私はCで宿題をコーディングだし、アップロードシステムは、私はあまりにも多くのスタックメモリを使用していると言われます。私はちょっとした問題として、問題の根源を見つけ出す必要があります。どのくらいのスタックメモリを使用していますか? <C>

私はスタックメモリの使用状況を分析したり、それを使用し、それらがどのくらい使用しているものの変数を参照する可能性のある方法はありますか?

編集:ここにコードがあります。これが意味する何等の

ので、私は私が使用していない任意の機能はありません願っています。(ケース1が正常に動作しているファイルはパラメータで起動したとき、これはケース2であるので)それは完全ではありませんそうするためにカエサル暗号を少し歪ませることです。入力時に、私は未知のサイズの2つの文字列を取得します。最初のものは暗号であり、2番目のものはデコードされたメッセージの近くにあるはずです(文字が欠けている可能性があり、余分な文字があるかもしれません)。コードは正常に動作し、必要なものはすべて出力されますが、長い文字列(それぞれ200文字など)を入力すると、アップロードシステムはあまりにも多くのスタックを使用していると言うことを開始します。

f.e.入力(ここではスクリーンショットhttps://imgur.com/a/gxWlZ

NOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM 
     abcRkfgchijklmnbCGqrstuvpxyzeABQDEFQGvIJKLMNOPRTUVWPZabcdefghijklnopdrPstuvwxorkCzABCEqFDpGHdJMNOPQcRSTUNVGYuZbMcTefghjklmnopqrstcvgwyzABCOiGHIPJKLMNOYPQRsTUWvYYZaQcdZpfgCfiXjekmnopqrptuvtwxyiABCDQFGHUEIJKLMQOPQRSTfVWXYZ 

と私は明らかにスタックメモリの185232Bを使用しました。

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

const char* alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 

char rotate(char, int); 
void shift(const char *src, char * dst, int offset); 
char * inputstr(size_t size); 
int edit_distance(const char *str1, const char *str2, int len1, int len2); 

int main(int argc, char * argv[]) 
{ 
    char * source = inputstr(10); 
    char * example = inputstr(10); 
    size_t len_source = strlen(source); 
    size_t len_example = strlen(example); 

    //char *closest = calloc(len_source+1,sizeof(char)); 
    char * destination = calloc(len_source + 1, sizeof(char)); 
    int min_match = len_source; 
    int best_i = 0; 
    for (int i = 0; i < 52;++i) 
    { 
     shift(source, destination, i); 
     int match = edit_distance(destination, example, len_source, len_example); 
     //printf("%2d: %s ~ %s > %d\n",i, destination, example, match); 
     if (match < min_match) { 
      min_match = match; 
      best_i = i; 
     } 
    } 
    shift(source, destination, best_i); 
    printf("%s\n", destination); 
    free(source); 
    free(example); 
    //free(closest); 
    free(destination); 
    return 0; 

} 

char rotate(char original, int offset) 
{ 
    int index; 
    char * rest; 
    rest = strchr(alphabet, original); 
    index = (int)(rest - alphabet); 
    int distance = (index + offset) % 52; 
    char new = *(alphabet + distance); 
    return new; 
} 

void shift(const char *src, char * dst, int offset) 
{ 
    int counter = 0; 
    int len = strlen(src); 
    for (int i = 0; i < len; ++i) 
    { 
     dst[i] = rotate(src[i], offset); 
     counter++; 
    } 

} 


char * inputstr(size_t size) 
{ 
    char * str; 
    if ((str = realloc(NULL, size * sizeof(char))) == NULL) { 
     printf("Not enough memory\n"); 
     free(str); 
     exit(69); 
    } 
    int ch; 
    size_t len = 0; 
    while ((ch = getchar()) != EOF && ch != '\n') { 
     if (isalpha(ch)) { 
      str[len] = ch; 
      ++len; 
      if (len == size) { 
       size *= 5; 
       if ((str = realloc(str, size * sizeof(char))) == NULL) { 
        printf("Not enough memory\n"); 
        free(str); 
        exit(69); 
       } 
      } 
     } else { 
      fprintf(stderr, "Error: Chybny vstup!\n"); 
      free(str); 
      exit(100); 
     } 
    } 
    str[len++] = '\0'; 
    return str; 
} 

int edit_distance(const char *str1, const char *str2, int len1, int len2) 
{ 
    int d[len1 + 1][len2 + 1]; 
    for (int i = 0; i <= len1; ++i) 
    { 
     d[i][0] = i; 
    } 
    for (int j = 0; j <= len2; ++j) 
    { 
     d[0][j] = j; 
    } 
    for (int j = 1; j <= len2; ++j) 
    { 
     for (int i = 1; i <= len1; 
     ++i) 
     { 
      if (str1[i - 1] == str2[j - 1]) { 
       d[i][j] = d[i - 1][j - 1]; 

      } else { 
       int min = d[i - 1][j] + 1; 
       if ((d[i][j - 1] + 1) < min) { 
        min = d[i][j - 1] + 1; 
       } 
       if ((d[i - 1][j - 1] + 1) < min) { 
        min = d[i - 1][j - 1] + 1; 
       } 
       d[i][j] = min; 

      } 
     } 
    } 
    //printf("%d %d\n", len1, len2); 
    /*for(int i = 0; i<=len1; ++i) 
    { 
     for(int j = 0; j<=len2; ++j) 
     { 
      printf("%2d ", d[i][j]); 
     } 
     printf("\n"); 
    }*/ 
    return d[len1][len2]; 
} 
+2

おそらく、大きすぎるローカル変数があります。コードを表示する。 – dbush

+0

デバッガがこれを手伝ってくれます。偶然、再帰関数を使用していますか? – Carcigenicate

+0

再帰を使用していません。 – Welsy

答えて

1

犯人はedit_distanceに、この配列のようになります。

int d[len1 + 1][len2 + 1]; 

この配列のサイズ(len_source + 1) * (len_example + 1) * sizeof(int)を持っています。たとえば、ソースとサンプルストリングがそれぞれ200バイトで、intが4バイトの場合、この配列にはおよそ200 * 200 * 4 = 160000バイトあります。それらは巨大な文字列ではありませんが、すでにスタック制限の3倍以上です。

その後
int i; 
int **d = malloc(sizeof(int *) * (len1 + 1)); 
for (i=0; i < len1 + 1; i++) { 
    d[i] = malloc(sizeof(int) * (len2 + 1)); 
} 

すると、あなたが保存していることを確認します

代わりにスタック上のこの配列を宣言するには、動的に(int型の配列を指すそれぞれのポインターの技術的配列、)2次元配列を割り当てることができます返す値をオフにしてすべてを解放します。

int result = d[len1][len2]; 
for (i=0; i < len1 + 1; i++) { 
    free(d[i]); 
} 
free(d); 
return result; 
+0

あなたが編集したコードの全体を入れてください。私はこれをどのように実装するのか完全に理解できません。 – Welsy

+0

@Welsy 'edit_distance'の先頭の配列宣言を動的割り当てのポインタで置き換え、最後にクリーンアップを行います。 – dbush

+0

パフォーマンスが重大である場合は 'malloca' /' freea'も使用してください。 – valdo

関連する問題