C 使用链接列表模拟外壳

C 使用链接列表模拟外壳,c,shell,memory,malloc,C,Shell,Memory,Malloc,现在我正在学习C,我的内存分配有问题,至少我从我的代码错误中了解到了这一点 代码 提前感谢您的支持。您没有为您的联系人字符串分配足够的资源 如果是“标准”字符串,则name和date只能放置一个字符,这意味着您只能处理空字符串(只有空字符才能结束它们) nume和内容有1个字符就足够了,然后终止的null字符就可以从分配的字符串中写出,valgrind指出情况就是这样 在mkdir中也有同样的问题 要方便地分配和复制,请使用strdup,否则请分配strlen(xx)+1以复制xx,因此请替换

现在我正在学习C,我的内存分配有问题,至少我从我的代码错误中了解到了这一点

代码


提前感谢您的支持。

您没有为您的联系人字符串分配足够的资源

如果是“标准”字符串,则name和date只能放置一个字符,这意味着您只能处理空字符串(只有空字符才能结束它们)

nume和内容有1个字符就足够了,然后终止的null字符就可以从分配的字符串中写出,valgrind指出情况就是这样

在mkdir中也有同样的问题

要方便地分配和复制,请使用strdup,否则请分配strlen(xx)+1以复制xx,因此请替换

并在mkdir中执行相同的操作


在makeroot中,您是这样做的

这是很危险的,因为如果你想释放资源,你必须记住不要尝试释放(*root)->name,不要有未定义的行为,不要冒险,我鼓励你也复制“/”


在deleteroot中,您什么也不做,因为您将root设置为NULL,然后释放,所以内存泄漏。您需要释放所有分配的资源,因此必须遍历所有树

您在rm中也有同样的问题

每次你有一个分配,你需要一个免费的


在ls中,不释放资源,只打印



您提供的所有代码似乎都放在头文件中,仅将结构定义和函数声明放在头文件中,将函数定义移动到源文件中,否则,如果在头文件中包含多次,您将多次定义函数,您没有为接触的字符串分配足够的资源

如果是“标准”字符串,则name和date只能放置一个字符,这意味着您只能处理空字符串(只有空字符才能结束它们)

nume和内容有1个字符就足够了,然后终止的null字符就可以从分配的字符串中写出,valgrind指出情况就是这样

在mkdir中也有同样的问题

要方便地分配和复制,请使用strdup,否则请分配strlen(xx)+1以复制xx,因此请替换

并在mkdir中执行相同的操作


在makeroot中,您是这样做的

这是很危险的,因为如果你想释放资源,你必须记住不要尝试释放(*root)->name,不要有未定义的行为,不要冒险,我鼓励你也复制“/”


在deleteroot中,您什么也不做,因为您将root设置为NULL,然后释放,所以内存泄漏。您需要释放所有分配的资源,因此必须遍历所有树

您在rm中也有同样的问题

每次你有一个分配,你需要一个免费的


在ls中,不释放资源,只打印



您提供的所有代码似乎都放在头文件中,仅将结构定义和函数声明放在头文件中,将函数定义移动到源文件中,否则如果在头文件中包含多次,您将多次定义函数

fyi,
root=NULL;自由根虽然合法,但却是导致内存泄漏的原因。事实上,唯一一次不是这样的是当
root
在输入时为null时。关于:
\uuu文件\u H\uuu
一个前导序列为系统“保留”建议删除前导下划线fyi,
root=null;自由根虽然合法,但却是导致内存泄漏的原因。事实上,唯一一次不是这样的是当
在条目上为空时。关于:
\uuu文件\u H\uuu
前导序列为系统“保留”时,建议删除前导下划线。Touch和mkdir具有相同的内存分配错误。谢谢你的回答。我会尽量多说的。我正在学习,是的,我知道,并在我的answer@georgian你明白我在回答中说的话吗?对不起。对我明白你说的话。现在我想知道如何实现它。你用你的例子救了我的命,而且非常明确。现在我在“ls”上遇到了另一个问题。两者都有。Touch和mkdir具有相同的内存分配错误。谢谢你的回答。我会尽量多说的。我正在学习,是的,我知道,并在我的answer@georgian你明白我在回答中说的话吗?对不起。对我明白你说的话。现在我想知道如何实现它。你用你的例子救了我的命,而且非常明确。现在我遇到了关于“ls”的另一个问题。
#ifndef __FILE_H__
#define __FILE_H__

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct Files Files;
typedef struct DirList DirList;
typedef struct NodeFile NodeFile;
typedef struct NodeDir NodeDir;

typedef struct Directory {
    // The name of the directory
    char *name;

    //  The list of files of the current directory
    Files *files;

    // The list of dirs of the current directory
    DirList *dirs;

    // The parent directory of the current directory (NULL for the root
    // directory)
    struct Directory *parentDir;
} Directory;


typedef struct File {
    // The name of the file
    char *name;

    // The size of the file
    int size;

    // The content of the file
    char *data;

    // The directory in which the file is located
    Directory *dir;
} File;

typedef struct Files {
    NodeFile *first;
    NodeFile *last;
} Files;

typedef struct DirList {
    NodeDir *first;
    NodeDir *last;
} DirList;

typedef struct NodeFile {
    struct NodeFile *next;
    struct NodeFile *prev;
    File *newfile;
} NodeFile;

typedef struct NodeDir {
    struct NodeDir *next;
    struct NodeDir *prev;
    Directory *newdir;
} NodeDir;

// create root of file system
void makeroot(Directory **root)
{
    *root = (Directory *) malloc(sizeof(Directory));

    (*root)->parentDir = NULL;
    (*root)->name = "/";
    (*root)->files = NULL;
    (*root)->dirs = NULL;
}

// remove root of file system
void deleteroot(Directory *root)
{
    root = NULL;
    free(root);
}

//add new file to current directory
File *touch(Directory *root, char *nume, char *content)
{
    NodeFile *new = (NodeFile *) malloc(sizeof(NodeFile));

    new->newfile = (File *) malloc(sizeof(File));

    new->newfile->name = (char *) malloc(sizeof(char));

    new->newfile->data = (char *) malloc(sizeof(char));

    strcpy(new->newfile->name, nume);
    strcpy(new->newfile->data, content);

    if (root->files == NULL) {
        root->files = (Files *) malloc(sizeof(Files));
        root->files->first = (NodeFile *) malloc(sizeof(NodeFile));
        root->files->last = (NodeFile *) malloc(sizeof(NodeFile));
        //if no file in folder root has first and last position
        root->files->first = new;
        root->files->last = new;
    } else if (strcmp(root->files->first->newfile->name,
                        new->newfile->name) > 0) {
        new->next = root->files->first;
        root->files->first = new;
    } else if (strcmp(root->files->last->newfile->name,
                        new->newfile->name) < 0) {
        root->files->last->next = new;
        root->files->last = new;
    } else {
        NodeFile *i = root->files->first;

        while (i != root->files->last) {
            if (strcmp(i->next->newfile->name,
                    new->newfile->name) > 0) {
                if (i == root->files->first->next)
                    i = root->files->first;
                i->next->prev = new;
                new->next = i->next;
                new->prev = i;
                i->next = new;
                break;
            }
            i = i->next;
        }
    }
    return new->newfile;
}

// Create directory
Directory *mkdir(Directory *parent, char *name)
{
    // la fel ca la touch
    NodeDir *new = (NodeDir *) malloc(sizeof(NodeDir));

    new->newdir = (Directory *) malloc(sizeof(Directory));

    new->newdir->name = (char *)malloc(sizeof(char));

    strcpy(new->newdir->name, name);
    new->newdir->parentDir = parent;

    if (parent->dirs == NULL) {
        parent->dirs = (DirList *)malloc(sizeof(DirList));
        parent->dirs->first = (NodeDir *) malloc(sizeof(NodeDir));
        parent->dirs->last = (NodeDir *) malloc(sizeof(NodeDir));
        parent->dirs->first = new;
        parent->dirs->last = new;
    } else if (strcmp(parent->dirs->first->newdir->name,
                        new->newdir->name) > 0) {
        new->next = parent->dirs->first;
        parent->dirs->first = new;
    } else if (strcmp(parent->dirs->last->newdir->name,
                        new->newdir->name) < 0) {
        parent->dirs->last->next = new;
        parent->dirs->last = new;
    } else {
        NodeDir *i = parent->dirs->first->next;

        while (i != NULL) {
            if (strcmp(i->newdir->name, new->newdir->name) > 0) {
                if (i == parent->dirs->first->next)
                    i = parent->dirs->first;
                i->next->prev = new;
                new->next = i->next;
                new->prev = i;
                i->next = new;
                break;
            }
            i = i->next;
        }
    }
    return new->newdir;
}

// traverse list and print files and folders names
void ls(Directory *parent)
{
    if (parent->files != NULL) {
        NodeFile *i;

        for (i = parent->files->first; i != NULL; i = i->next)
            printf("%s ", i->newfile->name);
        free(i);
    }

    if (parent->dirs != NULL) {
        NodeDir *j;

        for (j = parent->dirs->first; j != NULL; j = j->next)
            printf("%s ", j->newdir->name);
        free(j);
    }

    printf("\n");
}

// working directory
void pwd(Directory *dir)
{
    if (dir->parentDir == NULL)
        return;
    if (dir->parentDir != NULL) {
        pwd(dir->parentDir);
        printf("/%s", dir->name);
    }
}


Directory *cd(Directory *dir, char *where)
{
    if (strcmp(where, "..") == 0 && dir->parentDir != NULL) {
        return dir->parentDir;
    } else if (dir->dirs == NULL)
        printf("Cannot move to ‘%s’: No such directory!\n", where);
    else {
        NodeDir *it = dir->dirs->first;

        while (it != NULL) {
            if (strcmp(it->newdir->name, where) == 0) {
                dir = it->newdir;
                break;
            }
            it = it->next;
        }
        if (it == NULL)
            printf("Cannot move to ‘%s’: No such directory!\n",
                    where);
        free(it);
    }
    return dir;
}

void tree(Directory *parent, int i)
{

    if (i == 1)
        printf("\n%s\n", parent->name);
    if (parent->files != NULL) {
        NodeFile *it;

        for (it = parent->files->first; it != NULL; it = it->next) {
            if (i != 1) {
                int j;

                for (j = 0; j < i; j++)
                    printf("   ");
            }
            printf("   %s\n", it->newfile->name);
        }
        free(it);
    }
    if (parent->dirs != NULL) {
        NodeDir *it = parent->dirs->first;

        while (it != NULL) {

            int j;

            for (j = 0; j < i; j++)
                printf("   ");
            printf("%s\n", it->newdir->name);
            i = i + 1;
            tree(it->newdir, i);
            it = it->next;
            i = i - 1;
        }
        free(it);
    }
}


void rm(Directory *parent, char *dirname)
{ //it -- item
    NodeFile *it;

    for (it = parent->files->first; it != NULL; it = it->next) {
        if (strcmp(it->newfile->name, dirname) == 0) {
            if (it == parent->files->first) {
                parent->files->first =
                parent->files->first->next;
            } else if (it == parent->files->last) {
                parent->files->last = it->prev;
            } else {
                it->prev->next = it->next;
                it->next->prev = it->prev;
            }
            it = NULL;
            free(it);
            return;
        }
    }
    if (it == NULL) {
        printf("Cannot remove ‘%s’: No such file!\n", dirname);
        free(it);
    }
}


void rmdir(Directory *parent, char *dirname)
{

    NodeDir *it;

    for (it = parent->dirs->first; it != NULL; it = it->next) {
        if (strcmp(it->newdir->name, dirname) == 0) {
            if (it == parent->dirs->first) {
                parent->dirs->first =
                parent->dirs->first->next;
            } else if (it == parent->dirs->last) {
                parent->dirs->last =
                parent->dirs->last->prev;
            } else {
                it->prev->next = it->next;
                it->next->prev = it->prev;
            }
            it = NULL;
            free(it);
            return;
        }
    }
    if (it == NULL) {
        printf("Cannot remove ‘%s’: No such directory!\n", dirname);
        free(it);
    }
}

#endif
  touch x
==6012== Invalid write of size 1
==6012==    at 0x4C32E0D: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6012==    by 0x108ACA: touch (file.h:94)
==6012==    by 0x109746: main (main.c:83)
==6012==  Address 0x522d8f1 is 0 bytes after a block of size 1 alloc'd
==6012==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6012==    by 0x108A97: touch (file.h:90)
==6012==    by 0x109746: main (main.c:83)
==6012== 
==6012== Invalid write of size 1
==6012==    at 0x4C32E0D: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6012==    by 0x108AE5: touch (file.h:95)
==6012==    by 0x109746: main (main.c:83)
==6012==  Address 0x522d941 is 0 bytes after a block of size 1 alloc'd
==6012==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6012==    by 0x108AAC: touch (file.h:92)
==6012==    by 0x109746: main (main.c:83)
new->newfile->name = (char *) malloc(sizeof(char));
new->newfile->data = (char *) malloc(sizeof(char));
strcpy(new->newfile->name, nume);
strcpy(new->newfile->data, content);
new->newfile->name = (char *) malloc(sizeof(char));
new->newfile->data = (char *) malloc(sizeof(char));

strcpy(new->newfile->name, nume);
strcpy(new->newfile->data, content);
new->newfile->name = strdup(nume);
new->newfile->data = strdup(content);
 new->newfile->name = (char *) malloc(strlen(nume) + 1);
 new->newfile->data = (char *) malloc(strlen(content) + 1);

 strcpy(new->newfile->name, nume);
 strcpy(new->newfile->data, content);
(*root)->name = "/";
(*root)->name = strdup("/");