Reputation: 59
First, some background, I'm writing a file server for my systems programming class. What I have to do is write 4 client programs and a server to edit the directory of files client side. I've figured out how to actually do the transferring of the files client side, as well as how to actually get them through the socket, what I'm having a hard time doing is storing the files on the server. To try and solve this problem I've created 2 structs:
A FileSlot struct to store the file's name and contents in memory:
#ifndef __FILESLOT_H__
#define __FILESLOT_H__
#include "csapp.h"
typedef struct FILESLOT {
char *filename;
char *contents;
uint32_t length;
} FileSlot;
#endif
and a FileDrawer struct in order to actually keep track of the files on the server as I have to be able to add, remove, and list them:
#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
Basically I'm using these structs in a server loop, as the server receives the "put" command, I want the server to create a FileSlot, and stick it into the FileDrawer. In the past few days I've looked through the forums and so far learned that I need to use malloc(), which I'm a bit hazy on, but if I've learned correctly, I can create a pointer to a FileSlot allocated with malloc(), fill it with the necessary information, and then point one of the files[] elements from FileDrawer at the newly allocated FileSlot:
#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;
}
However This doesn't seem to work, I get really strange output from the print loop.
ALSO: Here's the implementations for my FileDrawer functions, in case I've mistyped anything here as well
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;
}
EDIT: I went in and fixed the mallocs, and removed the inefficiencies as suggested, so thanks for that! Now, my fdtest exits in a SEGFAULT at the first strcpy, and I can't figure out why. Any ideas?
Upvotes: 1
Views: 50
Reputation: 223689
Here's your main problem:
int i;
while (i < 5) {
You fail to initialize i
before using it. Because it is uninitialized, it's value is indeterminate and attempting to read it causes undefined behavior.
Initialize i
to 0 and it will behave properly.
int i = 0;
while (i < 5) {
Besides this, you have some inefficiencies in your code.
In new_fd
and add_file
, you copy the contents of a dereferenced pointer into a local variable, modify the local, then copy the contents back. That's unnecessary work. Just work directly on the passed-in pointer.
void new_fd(FileDrawer* fdp) {
fdp->drawerSize = 0;
}
void add_file(FileDrawer* fdp, FileSlot *fs) {
fdp->files[fdp->drawerSize] = fs;
fdp->drawerSize++;
}
You can perform similar changes in rem_file
.
Also, don't cast the return value of malloc, as it can hide subtle bugs.
Upvotes: 1