C 如何动态填充指向已创建结构的指针数组?

C 如何动态填充指向已创建结构的指针数组?,c,arrays,struct,C,Arrays,Struct,首先是一些背景知识,我正在为我的系统编程类编写一个文件服务器。我要做的是编写4个客户端程序和一个服务器来编辑客户端的文件目录。我已经知道了如何在客户端传输文件,以及如何通过套接字传输文件,我现在很难做到的是将文件存储在服务器上。为了尝试解决这个问题,我创建了两个结构: 用于在内存中存储文件名和内容的FileSlot结构: #ifndef __FILESLOT_H__ #define __FILESLOT_H__ #include "csapp.h" typedef struct FILESL

首先是一些背景知识,我正在为我的系统编程类编写一个文件服务器。我要做的是编写4个客户端程序和一个服务器来编辑客户端的文件目录。我已经知道了如何在客户端传输文件,以及如何通过套接字传输文件,我现在很难做到的是将文件存储在服务器上。为了尝试解决这个问题,我创建了两个结构:

用于在内存中存储文件名和内容的FileSlot结构:

#ifndef __FILESLOT_H__
#define __FILESLOT_H__

#include "csapp.h"

typedef struct FILESLOT {
        char *filename;
        char *contents;
        uint32_t length;
} FileSlot;

#endif
以及一个FileDrawer结构,以便实际跟踪服务器上的文件,因为我必须能够添加、删除和列出这些文件:

#ifndef __FILEDRAWER_H__
#define __FILEDRAWER_H__

#include "csapp.h"
#include "fileslot.h"

typedef struct FILEDRAWER {
        FileSlot* files[100];
        uint32_t drawerSize;
} FileDrawer;

void new_fd(FileDrawer *fd);

uint32_t get_size(FileDrawer *fd);

void add_file(FileDrawer *fd, FileSlot *fs);

void rem_file(FileDrawer *fd, int index);

int search_files(FileDrawer *fd, char *name);

#endif
基本上,我在服务器循环中使用这些结构,当服务器接收到“put”命令时,我希望服务器创建一个FileSlot,并将其粘贴到FileDrawer中。在过去的几天里,我浏览了论坛,到目前为止,我了解到我需要使用malloc(),这一点我有点不清楚,但是如果我学习正确,我可以创建一个指向分配了malloc()的文件批的指针,用必要的信息填充它,然后指向其中一个文件[]新分配的FileSlot处FileDrawer中的元素:

#include "filedrawer.h"
#include "fileslot.h"

int main(int argc, char** argv) {
        FileDrawer *fdp = (FileDrawer*)malloc(sizeof(FileDrawer));
        new_fd(fdp);

        int i;
        while (i < 5) {
                uint32_t length = i;
                FileSlot* fsp = (FileSlot*)malloc(sizeof(FileSlot));
                fsp->filename = "file name";
                fsp->contents = "contents";
                fsp->length = length;
                add_file(fdp, fsp);
                i++;
        }
        for(i = 0; i < fdp->drawerSize; i++) {
                printf("File Name %s \n", fdp->files[i]->filename);
        }
        free(fdp);
        return 1;
}
#包括“filedrawer.h”
#包括“fileslot.h”
int main(int argc,字符**argv){
FileDrawer*fdp=(FileDrawer*)malloc(sizeof(FileDrawer));
新(fdp),;
int i;
而(i<5){
uint32_t长度=i;
FileSlot*fsp=(FileSlot*)malloc(sizeof(FileSlot));
fsp->filename=“文件名”;
fsp->contents=“contents”;
fsp->长度=长度;
添加_文件(fdp、fsp);
i++;
}
对于(i=0;idrawerSize;i++){
printf(“文件名%s\n”,fdp->files[i]->filename);
}
自由党(fdp);
返回1;
}
然而这似乎不起作用,我从打印循环中得到了非常奇怪的输出

另外:这里是我的FileDrawer函数的实现,以防我在这里输入了错误的内容

void new_fd(FileDrawer* fdp) {
        FileDrawer fd;
        fd = *fdp;
        fd.drawerSize = 0;
        *fdp = fd;
}

uint32_t get_size(FileDrawer* fdp) {
        return fdp->drawerSize;
}    

void add_file(FileDrawer* fdp, FileSlot *fs) {
    FileDrawer fd = *fdp;
    fd.files[fd.drawerSize] = fs;
    fd.drawerSize++;
    *fdp = fd;
}

void rem_file(FileDrawer* fdp, int index) {
    FileDrawer fd;
    fd = *fdp;
    int i;
    for(i = index; i < fd.drawerSize; i++) {
            fd.files[i] = fd.files[i+1];
    }
    fd.drawerSize--;
    *fdp = fd;
}

int search_files(FileDrawer* fdp, char *name) {
    int i;
    int index = -1;
    for(i = 0; i < fdp->drawerSize; i++) {
            if ((fdp->files[i]->filename) == name) {
                        index = i;
                }
        }
        return index;
}
void new\u fd(FileDrawer*fdp){
文件抽屉fd;
fd=*fdp;
fd.drawerSize=0;
*fdp=fd;
}
uint32获取大小(文件抽屉*fdp){
返回fdp->付款人化;
}    
void add_文件(FileDrawer*fdp,FileSlot*fs){
FileDrawer fd=*fdp;
fd.files[fd.drawerSize]=fs;
fd.drawerSize++;
*fdp=fd;
}
无效rem_文件(FileDrawer*fdp,int索引){
文件抽屉fd;
fd=*fdp;
int i;
对于(i=索引;idrawerSize;i++){
if((fdp->files[i]->filename)==name){
指数=i;
}
}
收益指数;
}

编辑:我进去修复了mallocs,并按照建议消除了效率低下的问题,所以谢谢你!现在,我的fdtest在第一次strcpy时出现了一个SEGFAULT,我不知道为什么。有什么想法吗?

这是你的主要问题:

    int i;
    while (i < 5) {
除此之外,您的代码中还有一些低效之处

new_fd
add_file
中,将解引用指针的内容复制到局部变量中,修改局部变量,然后将内容复制回来。那是不必要的工作。只需直接处理传入的指针

void new_fd(FileDrawer* fdp) {
        fdp->drawerSize = 0;
}

void add_file(FileDrawer* fdp, FileSlot *fs) {
    fdp->files[fdp->drawerSize] = fs;
    fdp->drawerSize++;
}
您可以在
rem\u文件中执行类似的更改


另外,因为它可以隐藏细微的bug。

谢谢!听起来不错,我修正了malloc语句。我必须释放()我分配的每个文件段吗?或者结尾的free(fdp)语句也会处理这些问题吗?@AustinWilliams每次调用
malloc
都必须调用
free
。因此,您需要循环浏览
文件列表
,并对每个文件调用
free
。在您释放包含它们的fdp之前,请执行此操作。
void new_fd(FileDrawer* fdp) {
        fdp->drawerSize = 0;
}

void add_file(FileDrawer* fdp, FileSlot *fs) {
    fdp->files[fdp->drawerSize] = fs;
    fdp->drawerSize++;
}