在Eustis上检测到堆栈粉碎

时间:2015-10-14 06:58:38

标签: c dynamic-memory-allocation

当我在Windows / Eustis上编译并运行此程序时,我没有收到任何错误或警告。

该程序的基本功能是读入输入文本文件(源代码)并将C样式的注释/*........*/删除到文件cleaninput.txt

适用于Windows。但是,当在Eusis上运行时,我得到了这个:

gcc -o out.x a2.c
./out.x 
*** stack smashing detected ***: ./out.x terminated
Aborted

我尝试使用命令

进行编译
gcc -fno-stack-protector -o out.x a2.c
./out.x
*** Error in './out.x': double free or corruption (out): 0x09670440 ***
Aborted

我可以使用一个程序或实用程序来解决这个问题吗?

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


#define MAX_DEC_LENGHT 11
#define MAX_INTEGER 99999
#define MAX_LINE_WIDTH 100      //used in the struct below defines how wide a instruction can be per line

FILE *fp;


typedef struct input{
    char line[MAX_LINE_WIDTH];
    struct input *next;
}input;

void scanFile();
struct input *Push(struct input *temp2, char Buff[MAX_LINE_WIDTH]);
void printClean(struct input *temp);
int Get_No_Lines();
void freeme(struct input* ptr);
const char  *strip_comments(char input[MAX_LINE_WIDTH]);




int main(){
    int x = Get_No_Lines();
    scanFile(x);        //will read in the input and produce cleaninput.txt, get_no_lines is used to tell the program later how long the input text file is
    return(0);
}




/*
Take in an integer N, which represents how many lines there are in the text file, which is used in scanning into a linked list of each line
calls for the print clean input function
Currently not returning anything
*/
void scanFile(int n){   
    fp = fopen("input.txt", "r");
    struct input*temp = NULL;

    int i;

    for(i=0;i<n;i++){
        char Buff[MAX_LINE_WIDTH];
        fgets(Buff,MAX_LINE_WIDTH,fp);          //fgets is by far the easiest solution i found to scanning in line by line, the linked list is there for unlimited input lenght
        temp = Push(temp,Buff);     //push the value of fgets onto the linked list
    }
    printClean(temp);
    freeme(temp);               //at this point we call the printClean input function
    fclose(fp); 
}

/*
Take in the the pointer to a linked list, and place the value buff into the structs line segment,
Basic function is linked list push to end
*/
struct input *Push(struct input *temp2, char Buff[MAX_LINE_WIDTH]){
    struct input *temp=(struct input*)malloc(sizeof(struct input));
    struct input *current = temp2;
    strcpy(temp->line,Buff);
    temp->next= NULL;
        if(temp2==NULL){
            return(temp);       //base case if null
        }

        while(current->next!=NULL){
            current = current->next;        //insert to back of list
        }   
    current->next = temp;           //link the new node
    return(temp2);                  
}

/*
The main driver function for stripping the comments out of the input text file, 
calls the strip_comments function and places the result back into the struct, then prints to the file stream
currently not returing anythig, shouldnt need to, will be checked later -MM 
*/
void printClean(struct input *temp){
    fp = fopen("cleaninput.txt", "w");
    while(temp!=NULL){
        char t[MAX_LINE_WIDTH];
        strcpy(t,strip_comments(temp->line));                   //copy the contents of strip_comments into t, and then copy the contents of t into temp->line
        strcpy(temp->line, t);                                  //yeah im not sure why i need to strcpy's but it wouldnt work without them \_(?)_/¯
        fputs(temp->line, fp);
        temp=temp->next;        
    }
    fclose(fp);
}


const char *strip_comments(char input[MAX_LINE_WIDTH]){ 
    char output[100];

    int i=0;
    int x =0;

    int inComment = 0;  // a boolean variable to let the case statment change behavior in the while loop

    while(i<=MAX_LINE_WIDTH){
        if(inComment==1){
            if(input[i]=='*' && input[i+1]=='/'){
                inComment=0;
                i++;                                    //end the comment, and increment the counter up two to clear hte comment 
                i++;
            }
        }   
        if(inComment==0){
            if(input[i]=='/'&& input[i+1]=='*'){            //condtion to enter the comment switch
                inComment=1;                                            
        }else{              
            output[x] = input[i];           //if not in the comment and last check was not in comment push the value of input[i] to output[x] increment x
            x++;
        }
    }

        i++;
    }
    char *rtn = output;
    return(rtn);            //return the input free of comments, currently cannot handle multi_line comments
}


/*
Used for the scanning function, its sole purpose is to let the program know how many lines there are in the input text file
*/
int Get_No_Lines(){
    fp = fopen("input.txt", "r");

    int ch, number_of_lines = 0;
        do 
        {
            ch = fgetc(fp);
            if(ch == '\n')
                number_of_lines++;          //if the scanner gets to a \n charecter increment
        } while (ch != EOF);

        if(ch != '\n' && number_of_lines != 0)          // needs to be checked, method was adopted from the internet 
            number_of_lines++;  

    if(number_of_lines==0){     //i added this case in when we get a one line input that the user has not hit the /n or enter key
        number_of_lines =1; 
    }    

    fclose(fp);
    return(number_of_lines);
}

void freeme(struct input* ptr){
    struct input *temp;
    while(ptr!=NULL){
        temp=ptr->next;
        strcpy(ptr->line,"");
        free(ptr);
        ptr=temp;
    }
}

1 个答案:

答案 0 :(得分:1)

您正在返回一个指向局部变量char output[100];的指针,该变量调用未定义的行为。返回指向局部变量的指针始终是一个严重的错误。

相反,将output缓冲区作为参数传递给函数,并将分配留给调用者。

Can a local variable be accessed outside its scope?