我对C很新,我似乎无法弄清楚什么似乎是一个非常简单的指针问题。我的程序将行号添加到文件中。它逐行读入文件,然后在每行的开头添加一个行号。它可以单独在每个文件上正常工作,如下所示:
soccer@soccer-Dell-DV051:~/code C$ ./a.out test.c
soccer@soccer-Dell-DV051:~/code C$ ./a.out miscellaneousHeader.h
soccer@soccer-Dell-DV051:~/code C$ ./a.out test.c miscellaneousHeader.h
*** Error in `./a.out': free(): invalid next size (normal): 0x08648170 ***
Segmentation fault (core dumped)
soccer@soccer-Dell-DV051:~/code C$
但是当我一起运行它时,我得到了上述错误。以下代码是我的程序。
Compiler.c:
#include <stdio.h>
#include "lineNumAdderHeader.h"
#include "miscellaneousHeader.h"
int main(int argc, char *argv[]){
if (argc < 2)
fatal("in main(). Invalid number of arguments");
int i = 1;
while (i < argc){
lineNumAdder(argv[i]);
i++;
}
}
我已将问题缩小到lineNumPtr
。在第二个文件之后释放lineNumPtr
时发生错误。如果没有释放lineNumPtr
,我知道编程错误,程序运行正常。
lineNumAdder.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miscellaneousHeader.h"
#include "lineNumAdderHeader.h"
int lineSizeChecker(FILE*, int);
int lineNumChecker(char*);
int fileSizeChecker(FILE*);
void lineNumAdder(char* filename){
int lineSpace, position, lineNumCheckerBoolean, numOfDigits, fileSpace;
int lineNum = 1;
char *lineNumPtr = NULL;
char *numberedFile = NULL;
char *nonNumberedLine = NULL;
char *originalLine = NULL;
FILE *file = errorCheckedFopen(filename, "r+w");
while(1){
position = ftell(file);
if (position == 0){
fileSpace = fileSizeChecker(file);
numberedFile = errorCheckedMalloc(fileSpace);
}
lineSpace = lineSizeChecker(file, position);
if (position == 0)
originalLine = errorCheckedMalloc(lineSpace);
else
originalLine = realloc(originalLine, lineSpace);
if (fgets(originalLine, lineSpace, file) == NULL)
break;
lineNumCheckerBoolean = lineNumChecker(originalLine);
if (lineNumCheckerBoolean == 0){
if (position == 0)
nonNumberedLine = errorCheckedMalloc(lineSpace - 9);
else
nonNumberedLine = realloc(nonNumberedLine, lineSpace - 9);
strcpy(nonNumberedLine, &originalLine[9]);
}
else{
if (position == 0)
nonNumberedLine = errorCheckedMalloc(lineSpace);
else
nonNumberedLine = realloc(nonNumberedLine, lineSpace);
strcpy(nonNumberedLine, originalLine);
fileSpace += 8;
numberedFile = realloc(numberedFile, fileSpace);
}
numOfDigits = intDigitFinder(lineNum);
if (position == 0)
lineNumPtr = errorCheckedMalloc(numOfDigits);
else
lineNumPtr = realloc(lineNumPtr, numOfDigits);
sprintf(lineNumPtr, "%d", lineNum);
strcat(numberedFile, "/*");
strcat(numberedFile, lineNumPtr);
strcat(numberedFile, "*/");
if (lineNum < 10)
strcat(numberedFile, " ");
else if (lineNum >= 10 && lineNum < 100)
strcat(numberedFile, " ");
else if (lineNum >= 100 && lineNum < 1000)
strcat(numberedFile, " ");
else if (lineNum >= 1000 && lineNum < 10000)
strcat(numberedFile, " ");
strcat(numberedFile, nonNumberedLine);
lineNum++;
}
fclose(file);
free(originalLine);
free(nonNumberedLine);
free(lineNumPtr);
free(numberedFile);
}
int lineNumChecker(char *comment){
if (sizeOf(comment) < 8)
return 1;
if (comment[7] == '/' || comment[6] == '/' || comment[5] == '/' || comment[4] == '/')
return 0;
else
return 1;
}
int lineSizeChecker(FILE *file, int position){
int i = 2;
int ch;
while ((ch = fgetc(file)) != '\n' && ch != EOF)
i++;
fseek(file, position, SEEK_SET);
return i;
}
int fileSizeChecker(FILE *file){
int i = 2;
while (fgetc(file) != EOF)
i++;
fseek(file, 0, SEEK_SET);
return i;
}
miscellaneous.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miscellaneousHeader.h"
void fatal(char*);
int sizeOf(char *data){
int i = 1;
while(data[i-1] != '\n')
i++;
return i;
}
void *errorCheckedMalloc(size_t size){
void *ptr = malloc(size);
if (ptr == NULL)
fatal("in errorCheckedMalloc(). Memory Allocation Failure\n");
else
return ptr;
}
FILE *errorCheckedFopen(char *filename, char *mode){
FILE *file = fopen(filename, mode);
if (file == NULL)
fatal("in errorCheckedFopen(). File Opening Failure\n");
else
return file;
}
void fatal(char *errorMessage){
char* completedErrorMessage = errorCheckedMalloc(sizeOf(errorMessage)+17);
strcpy(completedErrorMessage, "[!!] Fatal Error ");
strcat(completedErrorMessage, errorMessage);
perror(completedErrorMessage);
free(completedErrorMessage);
exit(-1);
}
int intDigitFinder(int num){
int digits = 0;
do {
num /= 10;
digits++;
} while (num != 0);
return digits;
}
void *reMalloc(void *ptr, size_t size){
char buf[strlen(ptr) + 1];
strcpy(buf, ptr);
free(ptr);
ptr = errorCheckedMalloc(size);
if(size >= strlen(buf))
strcpy(ptr, buf);
return ptr;
}
我道歉了。这是我的第一篇文章,我想确保我为你们提供了足够的信息,以便给我最好的答案。谢谢你的任何和所有答案。他们非常感兴趣。
答案 0 :(得分:1)
lineNumAdder.c
文件。该程序现在每次读入时都会增加numberedFile
的大小。此外,第二个文件中出现错误,因为当我strcat
进入malloced区域时,行号已经是{存储在那里,所以numberedFile
会溢出。我已使用calloc
代替malloc
修复此问题。感谢所有给出答案并评论的人。他们都帮助很大。
这是完成的lineNumAdder.c文件:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "miscellaneousHeader.h"
#include "lineNumAdderHeader.h"
int lineSizeChecker(FILE*, int);
int lineNumChecker(char*);
int fileSizeChecker(FILE*);
void lineNumAdder(char* filename){
int lineSpace, filePosition, lineNumCheckerBoolean, numOfDigits;
int fileSpace = 0;
int lineNum = 1;
char *lineNumPtr = NULL;
char *numberedFile = NULL;
char *nonNumberedLine = NULL;
char *originalLine = NULL;
FILE *file = errorCheckedFopen(filename, "r+w");
while(1){
filePosition = ftell(file);
lineSpace = lineSizeChecker(file, filePosition);
if (filePosition == 0)
originalLine = calloc(1, lineSpace);
else
originalLine = realloc(originalLine, lineSpace);
if (fgets(originalLine, lineSpace, file) == NULL)
break;
lineNumCheckerBoolean = lineNumChecker(originalLine);
if (lineNumCheckerBoolean == 0){
fileSpace += lineSpace;
if (filePosition == 0){
nonNumberedLine = calloc(1, lineSpace - 8);
numberedFile = calloc(1, fileSpace);
}
else{
nonNumberedLine = realloc(nonNumberedLine, lineSpace - 8);
numberedFile = realloc(numberedFile, fileSpace);
}
strcpy(nonNumberedLine, &originalLine[9]);
}
else{
fileSpace += lineSpace + 9;
if (filePosition == 0){
nonNumberedLine = calloc(1, lineSpace);
numberedFile = calloc(1, fileSpace);
}
else{
nonNumberedLine = realloc(nonNumberedLine, lineSpace);
numberedFile = realloc(numberedFile, fileSpace);
}
strcpy(nonNumberedLine, originalLine);
}
numOfDigits = intDigitFinder(lineNum);
if(filePosition == 0)
lineNumPtr = calloc(1, numOfDigits);
else
lineNumPtr = realloc(lineNumPtr, numOfDigits);
sprintf(lineNumPtr, "%d", lineNum);
strcat(numberedFile, "/*");
strcat(numberedFile, lineNumPtr);
strcat(numberedFile, "*/");
if (lineNum < 10)
strcat(numberedFile, " ");
else if (lineNum >= 10 && lineNum < 100)
strcat(numberedFile, " ");
else if (lineNum >= 100 && lineNum < 1000)
strcat(numberedFile, " ");
else if (lineNum >= 1000 && lineNum < 10000)
strcat(numberedFile, " ");
strcat(numberedFile, nonNumberedLine);
lineNum++;
}
fclose(file);
free(originalLine);
free(nonNumberedLine);
free(lineNumPtr);
free(numberedFile);
}
int lineNumChecker(char *comment){
if (sizeOf(comment) < 8)
return 1;
if (comment[7] == '/' || comment[6] == '/' || comment[5] == '/' || comment[4] == '/')
return 0;
else
return 1;
}
int lineSizeChecker(FILE *file, int position){
int i = 2;
int ch;
while ((ch = fgetc(file)) != '\n' && ch != EOF)
i++;
fseek(file, position, SEEK_SET);
return i;
}
int fileSizeChecker(FILE *file){
int i = 2;
while (fgetc(file) != EOF)
i++;
fseek(file, 0, SEEK_SET);
return i;
}
答案 1 :(得分:0)
所以,很难调试这个...但至少:
int sizeOf(char *data) {
int i = 1;
while(data[i-1] != '\n' && data[i-1] != '\0')
i++;
return i;
}