当我在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;
}
}
答案 0 :(得分:1)
您正在返回一个指向局部变量char output[100];
的指针,该变量调用未定义的行为。返回指向局部变量的指针始终是一个严重的错误。
相反,将output
缓冲区作为参数传递给函数,并将分配留给调用者。