我得到一个“free():无效指针,Aborted(core dumped)”可能跟踪我正在进行的自由操作的消息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* ReadFile(char *filename)
{
char *buffer = NULL;
int string_size, read_size;
FILE *handler = fopen(filename, "r");
if (handler)
{
// Seek the last byte of the file
fseek(handler, 0, SEEK_END);
// Offset from the first to the last byte, or in other words,filesize
string_size = ftell(handler);
// go back to the start of the file
rewind(handler);
// Allocate a string that can hold it all
buffer = (char*) malloc(sizeof(char) * (string_size + 1) );
// Read it all in one operation
read_size = fread(buffer, sizeof(char), string_size, handler);
// fread doesn't set it so put a \0 in the last position
// and buffer is now officially a string
buffer[string_size] = '\0';
if (string_size != read_size)
{
// Something went wrong, throw away the memory and set
// the buffer to NULL
free(buffer);
buffer = NULL;
}
// Always remember to close the file.
fclose(handler);
return buffer;
}
return NULL;
}
int newLineCounter(char *string)
{
if(string==NULL)
return -1;
int count=0;
for(int i=0;((string[i])!='\0');i++)
{
if(string[i]=='\n')
count++;
}
return count;
}
char ** arrayOfWords(char *str,int max)
{
char **s;
s=malloc(max*(sizeof(char *)+1));
if(str==NULL||max<0)
return NULL;
int count=0;
char *temp=strtok(str,"\n");
int size=strlen(temp);
s[0]=malloc((sizeof(char *)*(size+1)));
s[0]=temp;
// int count=0;
while((s!=NULL)&&(count<max-1))
{
count++;
char *temp=strtok(NULL,"\n");
int size=strlen(temp);
s[count]=malloc((sizeof(char *)*(size+1)));
s[count]=temp;
}
count++;
s[count]="\0";
return s;
}
int main()
{
char *string = ReadFile("hi.txt");
if(string==NULL) {
printf("%s\n","Error,no files here" );
}
else {
int newLines=newLineCounter(string);
char **ret=arrayOfWords(string,newLines);
for(int i=0;i<newLines;i++)
{
printf("%s\n",ret[i] );
}
for(int i=0;i<newLines;i++)
{
free((ret[i]));
}
free(ret);
}
return 0;
}
所以我在我的arrayOfWords函数中为每个由新行字符分隔的“Word”分配内存。在我的main函数中打印完所有单词后,我首先尝试释放分配给每个单词的内存,然后希望释放指针当我尝试在gdb中调试它时,我在for循环中设置了一个断点,我试图释放每个引用。我在第二次迭代中得到一个SIGABRT,我很困惑为什么会发生这种情况。因此,当我试图在for循环中释放内容并且在释放实际指针之前很久就会发生错误。
干杯。
你在malloc
函数中使用char ** arrayOfWords(char *str,int max)
有问题
1>对于**s
函数内的双指针char ** arrayOfWords(char *str,int max)
。
s=malloc(max*(sizeof(char *)+1));
它应该是
s=malloc(max*sizeof(char *));
因为s是指向char指针数组的指针。
2>对于**s
内的每个项目。
s[0]=malloc((sizeof(char *)*(size+1)));
s[count]=malloc((sizeof(char *)*(size+1)));
他们应该是
s[0]=malloc((sizeof(char)*(size+1));
s[count]=malloc((sizeof(char)*(size+1)));
因为s [i]现在是指向字符数组的指针。
各种麻烦我认为char *temp = strtok(NULL, "\n");
是罪魁祸首。
strtok(str, "\n");
将邻近的"\n\n"
坍塌成一个标记,后来for (int i = 0; i < newLines; i++) { free((ret[i])); }
试图释放newLines
线,即使只分配了count
线。
代码也可能会错误地试图释放"\0"
其他困境
一个文件可能不会以'\n'
结尾,因此newLineCounter
会被一个文件关闭。
如果文件包含空字符,则newLineCounter()
将太小。
其他花絮
检查fseek(), ftell(), malloc()
的返回值
避免静默大小截断。 ftell()
返回long
,strlen()
返回size_t
。
一些未经测试的替代代码:
读一个文件
char *read_file(FILE *f, size_t *sz) {
if (fseek(f, 0, SEEK_END)) return NULL;
long len = ftell(handler);
// If trouble finding the end or file too big ...
if (len == -1 || (unsigned long) len >= SIZE_MAX) return NULL;
*sz = len;
rewind(handler);
char *buffer = malloc(sizeof *buffer * (*sz + 1));
size_t read_size = fread(buffer, sizeof *buffer, *sz, f);
// Reading less than expected is not certainly wrong as the
// ftell technique is not _the_ best way to find file size,
// It may overstate.
// More robust code would use another approach.
buffer[read_size] = '\0';
*sz = read_size;
return buffer;
}
计数线
size_t newLineCounter(const char *mem, size_t sz) {
size_t count=0;
for(size_t i=0; i < sz; i++) {
count += mem[i] == '\n';
}
if (i > 0 && mem[sz-1] != '\n') count++;
return count;
}
线阵列
char **arrayOfLines(char *str, size_t sz, size_t line_count) {
char **lines = malloc(sizeof *lines * (line_count + 1));
if (lines == NULL) return NULL;
for(size_t i=0; i < line_count; i++) {
const char *eol = memchr(str, '\n', sz);
size_t len;
if (eol == NULL) {
len = sz;
} else {
len = (size_t)(eol - str + 1);
}
lines[i] = malloc(len + 1);
if (lines[i]) {
memcpy(lines[i], str, len);
lines[i][len] = '\0';
}
str += len;
sz -= len;
}
lines[line_count] = NULL;
return lines;
}