0

私はCコード(私が今までに書いた最初のCコード)を持っていて、それにエラーがありますが、どこにあるのかわかりません。変数を解放しようとすると(動的に割り当てられ、その名前はout_htmlです)、二重に解放されるか、破損します。私のプログラムがなぜこれを行うのか分かりません、私はすべての通話を無料でチェックしました。

コード:

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

#include "fcntl.h"
#include "errno.h"

#include "sys/types.h"
#include "sys/stat.h"

#include "unistd.h"

#define MAX_SIZE 512

typedef struct node
{
    char* data;
    struct node * nextnode;
} node;

int max(int a, int b)
{
    if(a>b) return a;
    else return b;
}

node* push(node * stackTop, char* data)
{
    //static 
    node* newItem;

    newItem = calloc(sizeof(node),1);
    newItem->data = data;
    newItem->nextnode = stackTop;

    return newItem;
}

node* pop(node* stackTop)
{
    if(stackTop != NULL)
    {
        free(stackTop->data);
        node* P = stackTop;
        return stackTop->nextnode;
        free(P);
    }else return NULL;
}

int isMajorTag(char* tag)
{
    if(strcmp(tag, "<html>") == 0 || strcmp(tag, "</html>") == 0 ||
       strcmp(tag, "<body>") == 0 || strcmp(tag, "</body>") == 0 ||
       strcmp(tag, "<head>") == 0 || strcmp(tag, "</head>") == 0 ) { return 1; }
    else                         { return 0; };
}

int isHTMLtag(char* tag, char* tags)
{
    char* tag2;
    if(strstr(tag," ") != NULL)
    {
        char* strptr = strstr(tag, " ");
        int End = strptr - tag;
        char* tag_ = strndup(tag, End);
        tag2 = calloc((strlen(tag_) + strlen("*") + 2), sizeof(char));
        strcpy(tag2, tag_);
        strcat(tag2,"*");
        free(tag_); 
    } 
    else tag2 = tag;
    int ret;
    if(strstr(tags, tag2) != NULL){ ret =  1; }
    else                         { ret = 0; };
    if(tag2 != tag ) free(tag2); 
    return ret;
}

int isCloserTagOf(char* cltag, char* tag)
{
    int ret = 1;
    if( cltag[1] != '/' ) ret = 0;
    if( tag[1] == '/' ) ret = 0;
    char* ntag;
    char* ncltag;
    if(strstr(tag," ") != NULL)
    {
        char* strptr = strstr(tag, " ");
        int End = strptr - tag;
        ntag = strndup(tag, End) + 1;
        // ntag = calloc(strlen(ntag0) + 1 + 1, sizeof(char)); strcpy(ntag, ntag0); strcat(ntag, ">");
        ncltag = strndup(cltag+2,strlen(cltag) - 3);
    } else
    {
        ntag = tag + 1;
        ncltag = cltag + 2;
    }
//  printf("|%s|%s|  %i", ntag, ncltag, strcmp(ncltag, ntag));

    if(strcmp(ncltag, ntag) != 0) ret = 0;
    return ret;
}

int isIndividualTag(char* tag)
{
    if(strcmp(tag,"</br>") == 0) return 1;
    else if(strncmp(tag,"<!--#include file=",18) == 0) return 2;
    else if(strncmp(tag,"<!--#echo var=",14) == 0) return 3;
    else if(strncmp(tag,"<!--",4) == 0) return 4;
    else return 0;
}

int main(int argc,char *argv[])
{
    char* fname;
    if(argc == 2)
    {
        fname = argv[1];
    } else
    {
        printf("Give me a filename!");
        fname = calloc( MAX_SIZE, sizeof(char));
        scanf("%s", fname);
    };
    printf("Parameter: %s \n\n", fname);

// beolvasas
    int f = open(fname, O_RDONLY);
    long pos = lseek(f, 0, SEEK_END);
    lseek(f, 0, SEEK_SET);

    char *buff = calloc(pos,1);
    read(f, buff, pos);
    close(f);

    f = open("valid-tags", O_RDONLY);
    pos = lseek(f, 0, SEEK_END);
    lseek(f, 0, SEEK_SET);

    char *valids = calloc(pos,1);
    read(f, valids, pos);
    close(f);

//  printf("File: %s %s %i   ",buff, valids, isCloserTagOf("</html>","<html>")); printf("Igen? %i", isHTMLtag("</head>",valids));

    node* Stack = NULL;
    char *P = buff;
    int is_valid = 1;
    int bodyCnt = 0;
    char* body[6];
    int correct_body = 1;
    char* out_html = calloc(strlen(buff), sizeof(char));
    while(P[0] != '\0' )
    {
        if(P[0] == '<')
        {
            char* strptr = strstr(P, ">");
            if(strptr != NULL)
            {
                int nextCloser = strptr - P + 1;
                char* tag = strndup(P, nextCloser);
                int IsIndividual = isIndividualTag(tag);
                if(isHTMLtag(tag, valids) || IsIndividual)
                {
                    if(IsIndividual)
                    { 
                        if(IsIndividual == 2) // file inclusion
                        {
                            char* firstQ = strstr(tag, "\"");
                            char* secondQ;
                            if( firstQ ) secondQ = strstr(firstQ + 1, "\"");

                            if( firstQ && secondQ )
                            {
                                char* incl_filename = strndup((firstQ + 1), (secondQ - firstQ - 1));
                                f = open(incl_filename, O_RDONLY);
                                pos = lseek(f, 0, SEEK_END);
                                lseek(f, 0, SEEK_SET);
                                char *inclstr = calloc(pos,1);
                                read(f, inclstr, pos);
                                close(f);
                                char* new_out_html = calloc((max(strlen(buff),strlen(out_html)) + pos + 1 + 1 + 1), sizeof(char));
                                strcpy(new_out_html, out_html);
                                strcat(new_out_html, inclstr);
                                free(out_html); out_html = NULL; // free(inclstr);
                                out_html = new_out_html; 
                            } else
                            {   
                                printf("Invalid file inclusion! \n");
                                is_valid = 0; break;
                            };
                        } else if (IsIndividual == 3) // date time
                        {
                            time_t t = time(NULL);                  
                        //  int nDigits = floor(log10(abs(t)) + 1; (strlen(out_html) + nDigits
                            char* timestring = ctime(&t);
                            char* new_out_html = calloc(1 + max(strlen(buff),strlen(out_html)) + strlen(timestring), sizeof(char));
                            strcpy(new_out_html, out_html);
                            strcat(new_out_html, timestring);
                            //printf("%s",new_out_html);
                            free(out_html); out_html = NULL; // free(timestring);
                            out_html = new_out_html;  
                        } else
                        {
                            strcat(out_html, tag);
                        };
                    }else
                    {
                        strcat(out_html, tag);
                        if(Stack != NULL && isCloserTagOf(tag,Stack->data))
                        {
                            Stack = pop(Stack);
                        }else
                        {
                            Stack = push(Stack, tag);
                        };
                    } 
                    if(isMajorTag(tag))
                    {   
                        if(bodyCnt < 6)
                        {   body[bodyCnt] = calloc(strlen(tag), sizeof(char));
                            strcpy(body[bodyCnt],tag);
                            ++bodyCnt;
                        }else
                        {   
                            printf("Too much major html tag found...");
                            correct_body = 0;
                        }
                    }
                }else
                {
                    printf("Invalid html tag: %s \n", tag);
                    is_valid = 0;
                    break;
                }
                P = P + nextCloser;
            } 
            else
            {
                printf("Unclosed tag\n");
                is_valid = 0;
                break;
            }
        } else
        {  //printf("-%c",P[0]);
           strncat(out_html, P,1); 
        //  printf("{(%s)}",out_html);
           P = P + 1;
        };
    };

    int i;
    char* correctBody[] = { "<html>", "<head>", "</head>", "<body>", "</body>", "</html>"};
    for(i = 0; i < bodyCnt && correct_body; ++i) {
            correct_body = (strcmp(body[i],correctBody[i]) == 0); }
    if(is_valid && Stack == NULL && 
       correct_body && bodyCnt == 6){ printf("\nValid HTML Code\n");
                                      printf("\n\n%s\n",out_html);
                                        }
    else                              printf("\nInvalid.\n");

//  printf("%i %i %i",bodyCnt,correct_body,is_valid);
    /*****************************************************************/
    for(i=0;i<bodyCnt;++i) free(body[i]);
    free(buff); free(valids); // 
    if(out_html != NULL) free(out_html);
    return 0;
}

コードの最後:if(out_html!= NULL)free(out_html); これがなければ、クラッシュは発生しません。

クラッシュは196行目近くで発生したと思います。

(適切なhtmlタグを持つvalig-htmlファイルが必要です-これがないと、コードは役に立ちません。つまり、次のようなファイルです:)

4

3 に答える 3

1

コードで何が起こっているのかを理解するのは難しいですが、いくつかの潜在的に無意味な操作が一目でわかります。たとえば、このシーケンスを考えてみましょう

int f = open(fname, O_RDONLY);
long pos = lseek(f, 0, SEEK_END);
lseek(f, 0, SEEK_SET);

char *buff = calloc(pos,1);
read(f, buff, pos);
close(f);
...

char* out_html = calloc(strlen(buff), sizeof(char));

あるファイルの内容を割り当てられたバッファに読み込みますbuff(バッファのサイズは正確にファイルのサイズです)。その後buff、nullで終了する文字列として扱います。これをの引数として使用しますstrlen

buffしかし、あなたは自分の!をnullで終了することを決して気にしませんでした。これはどのように機能するはずですか?nullで終了していない場合、それは文字列ではなく、の引数として意味のある形で使用することはできませんstrlen

プログラムには、同じパターンに従うコードのインスタンスがいくつか含まれています。ファイルの内容全体が正確なサイズのバッファに読み込まれ、nullで終了する文字列として解釈されますが、実際にはnullで終了しません(誰も気にしません)ヌル終了を確実にするため)。

終了ゼロはファイル自体に存在することになっていますか?もしそうなら、どうやってそれを知ることになっていますか?ここではテレパシーではありません。

于 2012-10-06T06:38:10.287 に答える
0

エラーメッセージは少し混乱する可能性があります。

割り当てがcallocで200バイトと言うと、ルーチンは内部で少し多くを割り当てます。
たとえば、8、16、または32バイトを割り当てて、リンクリストやその他の簿記を作成します(つまり、解放されています)。

strcpy / strcatで追加またはコピーされた文字列がターゲット配列に適合しない場合、内部的に簿記が破損する可能性があります。

したがって、エラーは必ずしもポインタを2回解放しても何も起こりません。

于 2012-10-06T07:16:34.777 に答える
0

これは間違っているように見えます:(BTW:stackTopの定義/宣言が見つかりませんでした)

node* pop(node* stackTop)
{
    if(stackTop != NULL)
    {
        free(stackTop->data);
        node* P = stackTop;
        return stackTop->nextnode;
        free(P);
    }else return NULL;
}

短すぎる別のcalloc()があります。(strcpy()は、calloc()されたオブジェクトに属していない場所にそのnulバイトを配置します。ところで:sizeof(char)は定義上1です。

                    if(bodyCnt < 6)
                    {   body[bodyCnt] = calloc(strlen(tag), sizeof(char));
                        strcpy(body[bodyCnt],tag);
                        ++bodyCnt;
                    }else
                    {   
                        printf("Too much major html tag found...");
                        correct_body = 0;
                    }
于 2012-10-06T07:40:28.827 に答える