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