我正在使用C程序循环我的文件结构。我点击了一个新文件夹,我将它附加到链接列表的路径,以便我可以迭代地浏览所有子目录。
该计划包括:
main函数,调用迭代函数(循环遍历文件)
一旦一切正常,我循环遍历所有文件。但是当我在main函数中有一个while循环来更频繁地调用迭代函数时,由于segmenatation错误,它总是在第二次失败。
所以我正在调查一下,似乎链表中的一个元素的地址无效。
我的元素的所有地址都具有以下格式和长度:0x2398ff0或0x2398ee0
然而,非法指针的地址为0x7f3770304c58
有没有人有任何想法为什么这个地址这么久?
我已经检查了每个添加到链表的新地址的printf("%p",元素),并且该地址在代码之前从未出现过。它似乎神奇地出现了。
我正在考虑一个狂野的指针,但在我释放任何指针后我将其设置为NULL,这应该阻止这个吗?
感谢任何提示。我现在还没有发布代码,因为它很长,并且认为可能有明显的事情,我只是看不到。
编辑:整个代码,包括主要功能
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
void iterativefile(FILE *f, char** field, int looper){
DIR *d;
struct dirent *dir;
typedef struct nextpath { // Define element type of linked list
char *thispath;
struct nextpath *next;
}nextpath;
nextpath *startpath = malloc(sizeof(nextpath));
char * beginning = (char *) malloc(2); //create first element in linked list, starting on root node "."
strcpy(beginning, ".");
startpath->thispath = beginning;
int found = 0;
nextpath *currentzeiger = startpath;
nextpath *firstelement = startpath;
char *newdir, *currentfile, *currentpath;
do {
currentpath = currentzeiger->thispath;
d = opendir(currentpath);
if (!d){ //IF the path is invalid or cannot be opened
firstelement = currentzeiger->next;
free(currentzeiger);
currentzeiger = firstelement;
continue;
}
while((dir = readdir(d)) != NULL){
if (dir->d_type != DT_REG){ // current element is a directory -> add it to linked list
if (strcmp(dir->d_name, ".") != 0 && strcmp(dir->d_name, "..") != 0){
newdir = (char *) malloc(2+strlen(currentpath) + strlen(dir->d_name));
strcpy(newdir, currentpath);
strcat(newdir, "/");
strcat(newdir, dir->d_name);
nextpath *new = malloc(sizeof(nextpath)); // add new folder to linked list
new->thispath = NULL;
new->thispath = strdup(newdir);
new->next = currentzeiger->next;
currentzeiger->next = new;
free(newdir);
newdir = NULL;
}
}
else { // current element is a file -> check if already included in list, if not, add it
currentfile = (char *) malloc(2+strlen(currentpath)+strlen(dir->d_name));
strcpy(currentfile, currentpath);
strcat(currentfile, "/");
strcat(currentfile, dir->d_name);
found = 0;
if (field != NULL) {
for (int z = 0; z < looper; z++){
if (field[z] != NULL){
if(strcmp(currentfile,field[z]) == 0){
found = 1;
free(field[z]);
field[z] = NULL;
}
}
}
}
if (found == 0){
char *renamefile = (char *) malloc(strlen(currentpath) + 6);
strcpy(renamefile, currentpath);
strcat(renamefile, ".cbsm");
free(renamefile);
renamefile = NULL;
}
free(currentfile);
currentfile = NULL;
}
}
firstelement = currentzeiger->next;
free(currentzeiger->thispath);
currentzeiger->thispath = NULL;
free(currentzeiger);
currentzeiger = firstelement;
closedir(d);
}while(currentzeiger != NULL);
}
int main()
{
int counterofwhile = 1;
while(1){
printf("Loop number: %d\n", counterofwhile);
counterofwhile++;
FILE *fp = fopen("datasyn.txt", "rw+");
if (fp == NULL) {
printf("FILE ERROR");
FILE *fp = fopen("datasyn.txt", "ab+");
iterativefile(fp, NULL, 0);
}
else {
int lines = 0;
int ch = 0;
int len = 0;
int max_len = 0;
while((ch = fgetc(fp)) != EOF){
++len;
if (ch == '\n'){
if(max_len < len)
max_len = len;
++lines;
len = 0;
}
}
if (len)
++lines;
fprintf(stderr, "%d lines\n", lines);
if (lines > 0){
int numProgs = 0;
char *programs[lines];
char line[max_len + 1];
rewind(fp);
while(fgets(line, sizeof(line), fp)){
int new_line = strlen(line) - 1;
if (line[new_line] == '\n')
line[new_line] = '\0';
programs[numProgs++] = strdup(line);
}
iterativefile(fp, programs, numProgs);
for (int j = 0; j < numProgs; j++){
free(programs[j]);
}
}
else {
iterativefile(fp, NULL, 0);
}
sleep(1);
printf("Done\n");
fclose(fp);
}
}
return 0;
}
答案 0 :(得分:2)
在功能iterativefile()
中,您不能使用calloc()
分配startpath
,也不会将startpath->next
设置为空。 malloc()
返回的内存不一定归零。当你随后使用startpath->next
时,一切都会破裂。
您也不会使用传递给iterativefile()
的文件指针。从定义中删除参数后,您可以更改通话,并且fp
中有main()
的阴影(在if (fp == NULL)
区块中,您创建了一个新的{{ 1}}这真的不需要)。它真的不清楚还有什么意思发生;您没有明确说明该计划的目的是什么。我没有FILE *fp
文件,但由于未使用文件流,因此无关紧要。我从代码中获得了许多像datasyn.txt
这样的行,但是之前我没有崩溃。
使用更多警告选项进行编译。我调用了文件FILE ERRORLoop number: 280
并使用以下方法编译了我的黑客版本
fp17.c
通过一些其他简单的更改(gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition fp17.c -o fp17
在函数之前; static
),代码干净地编译(并且如果没有&#39;则需要int main(void)
来发现阴影。我找到了一个未使用的变量警告,指出了它。