我正在做一个项目,在这个程序中我想逐行读取给定的 txt 文件。用空格分隔每一行,并在该行中获取单词数组。完成该操作后,我想释放所有 mallocs,但当我尝试释放它时会出现错误。
FILE * filePointer;
char * lineFromText = NULL;
size_t lengthOfLine = 0;
ssize_t lastIndexOfText;
filePointer = fopen("/home/ogr/b21xxxxxxx/input5.txt", "r");
if (filePointer == NULL)
exit(EXIT_FAILURE);
char **array=malloc(sizeof(char*)*10);
int i;
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
while ((lastIndexOfText = getline(&lineFromText, &lengthOfLine, filePointer)) != -1)
{
lineFromText[lastIndexOfText-2]=' ';
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
while (pch != NULL)
{
int loop;
array[0]=pch;
if(array[0]==NULL) {
printf("No test to search.n");
exit(0);
}
for(loop=1;loop<10;loop++) {
array[loop]=strtok(NULL," ");
if(array[loop]==NULL)
break;
}
for(loop=0;loop<10;loop++) {
if(array[loop]==NULL)
break;
printf("Item #%d is %sn",loop,array[loop]);
}
pch = strtok (NULL, " ");
}
}
fclose(filePointer);
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
你可以从这里看到文本文件:input5.txt
你在free上得到错误的原因是你破坏了最初由malloc返回的指针。但真正的原因在更深的地方。
让我们先处理这个免费错误。以下是分配内存的方法:
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
在这里,10 个数组条目中的每一个都分配了malloc
调用返回的指针。每个指针都指向分配的 40 或 80 字节内存块(sizeof(char*)
在 x86 上给出 4 个,在 x64 上给出 8 个(。
为了释放该内存,应该将malloc
返回的指针传递给free
函数:
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
但由于以下代码,它在您的情况下不起作用:
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
while (pch != NULL)
{
int loop;
array[0]=pch;
...
for(loop=1;loop<10;loop++) {
array[loop]=strtok(NULL," ");
if(array[loop]==NULL)
break;
}
在这里,您将覆盖最初由malloc
返回并存储在array
中的地址与strtok
返回的地址。因此,所有分配的内存都被泄漏,当涉及到array[0]
包含pch
地址(最后一行的第一个单词(free
并且array[1]
包含pch
加上第二个单词偏移地址时,您会得到错误原因,该地址已经在第一个周期迭代中释放。
这里真正的事情是,除了由getline
完成的内存分配之外,您真的不需要任何额外的内存分配。首先,您可以声明一个静态分配的指针数组:
char *array[10];
而不是:
char **array=malloc(sizeof(char*)*10);
int i;
for (i=0; i<10; i++) {
array[i] = malloc(10 * sizeof(char*));
}
然后像这样初始化pch
:
char *pch = strtok (lineFromText," ");
而不是:
char * pch = malloc(10 * sizeof(char));
strcpy(pch,strtok (lineFromText," "));
处理完成后,只剩下释放缓冲区lineFromText
因为它由getline
分配:
free(lineFromText)
而不是:
int j;
for (j = 0; j < 10 ; j++) {
free(array[j]);
}
希望这有帮助。祝你好运。