C在循环

时间:2016-08-13 01:07:58

标签: c pointers

我正在使用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;
}

1 个答案:

答案 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)来发现阴影。我找到了一个未使用的变量警告,指出了它。