C: how do dynamically allocate & free memory for a char array? -


how dynamically allocate , free memory char array?

my malloc below not work. error thrown 'expected ';' @ end of declaration list.'

char *string_buffer = malloc(128 * sizeof(char)); 

below attempt @ freeing string_buffer[128] char array:

void rmv(struct tree_node *cwd) {     struct list_node *child = cwd -> first_child;     free(string = child -> tree -> string_buffer);      printf("string memory free successful\n");     //free(cwd -> first_child -> tree);     //free(cwd -> first_child); } 

rest of code:

shell commands:

cd = current directory

ls = list

mkdir = make directory

rmdir = remove directory (unimplemented - need free memory)

#include <stdio.h> /* fgets(), fprintf() , printf() */ #include <stdlib.h> /* exit_failure */ #include <ctype.h> /* isspace() */ #include <string.h> #include <stddef.h>  // commands char exitprogram[] = "exit"; char listdirectory[] = "ls"; char commanddirectory[] = "cd"; char makedirectory[] = "mkdir"; char removedirectory[] = "rmdir";  // holds string buffer of length 128 // pointer parent // pointer first node of list of children typedef struct tree_node {     char string_buffer[128];     struct tree_node *parent;     struct list_node *first_child; // first node of list of children? } tree_node;  // pointer tree node // pointer next item in list typedef struct list_node {     struct tree_node *tree;     struct list_node *next; } list_node;  // allocates right amount of space tree node // sets pointers null // initialises string buffer given name // returns pointer tree node struct tree_node *make_tree_node(char *name) {     tree_node *instance = malloc(sizeof(*instance));     instance -> parent = null;     instance -> first_child = null;     strcpy(instance -> string_buffer, name);     return instance; }  // allocates new list node // assigns fields tree node references , next list node // returns pointer new list node struct list_node *make_list_node(struct tree_node *v, struct list_node *next) {     list_node *instance = malloc(sizeof(*instance));     instance -> tree = v;     instance -> next = next;     return instance; }  // checks whether directory named arg exists in current working directory // creates directory if not exist // if arg null, function should print error message void do_mkdir(struct tree_node *cwd, char *arg) {      //printf("making directory name %s\n", arg);      if (null == arg || !strcmp(arg, "")) {         printf("please specify directory name not null: mkdir directoryname\n");     }     else {         // check if directory exists         struct list_node *subdir = cwd->first_child;          while (subdir != null) {             if (strcmp(subdir -> tree -> string_buffer, arg) == 0) {                 printf("directory name exists. please provide name.\n");                 return;             }             subdir = subdir -> next;         }          // adding new directory         struct tree_node *newsubdir = make_tree_node(arg);         newsubdir -> parent = cwd;         struct list_node *newlistnode = make_list_node(newsubdir, null);          // putting new node in alphabetical order         struct list_node *prev = null;         if (subdir == null) {             newlistnode -> next = cwd -> first_child;             cwd -> first_child = newlistnode;         } else {             while (subdir != null) {                 // todo: use case insensitive compare                 if (strcmp(arg, subdir -> tree -> string_buffer) > 0) {                     // inserting in front                     newlistnode -> next = subdir -> next;                     prev->next = newlistnode;                     break;                 }                 prev = subdir;                 subdir = subdir -> next;             }             if (subdir == null) {                 subdir->next = newlistnode;             }         }     } }  // prints children of directory cwd (not recursively) void do_ls(struct tree_node *cwd) {     printf("listing directories...\n");     struct list_node *subdir = cwd -> first_child;     while (subdir != null) {         printf("%s\n", subdir ->tree -> string_buffer);         subdir = subdir->next;     } }  // *checks whether cwd has subdirectory named arg // *if yes, function returns corresponding tree node (and become new working directory) // *if no, prints error message // *handle cd , cd .. struct tree_node *do_cd(struct tree_node *cwd, struct tree_node *root, char *arg) {      // initialising subdir cwd's first child     struct list_node *subdir = cwd -> first_child;      // initialising pardir cwd's parent     struct tree_node *pardir = cwd -> parent;      if (pardir != null) { // root directory not have parent directory         if (strcmp(arg, "..") == 0) {             cwd = pardir;             printf("returning parent directory.\n");             return cwd;         }     }     // checks if user input argument "."     if (strcmp(arg, ".") == 0) {         return cwd;     }      // checks if user input argument null or ""     if (null == arg || !strcmp(arg, "")) {         printf("returning root directory.\n");         return root;     }      // checks if cwd has subdirectory named arg     while (subdir != null) {         if (strcmp(subdir -> tree -> string_buffer, arg) == 0) {             printf("subdirectory exists!\n");             cwd = subdir-> tree;             printf("making & entering subdirectory: %s\n", arg);             return cwd;         }         subdir = subdir-> next;     }     printf("directory not exist!\n");     return cwd; }  // *prints prompt (e.g. /bar/baz/ >) in every iteration of main loop // *show directories on path in correct order void show_prompt(struct tree_node *cwd) {     struct tree_node *originaldir = cwd;     if (cwd -> parent != null) {         show_prompt(cwd -> parent);         printf("/%s", cwd -> string_buffer);     }     cwd = originaldir; }  // *removes node child parent node dir // *take care correctly support corner cases child being 1 // *all memory occupied child should freed void remove_child(struct tree_node *cwd, struct tree_node *child) {     child = cwd -> first_child -> tree;     cwd = child -> parent;     if (cwd -> first_child -> tree == null) {         printf("subdirectory not empty!\n");     }     else if (cwd -> first_child != null) {         free(child);     } }  void rmv(struct tree_node *cwd) {     struct list_node *child = cwd -> first_child;     printf("%s\n", child -> tree -> string_buffer);     strcpy(child -> tree -> string_buffer, "");     printf("string memory free successful\n");     free(child -> tree -> string_buffer);     //free(cwd -> first_child -> tree);     //free(cwd -> first_child); }  void rmv2(struct tree_node *cwd) {     struct tree_node *child = cwd -> first_child -> tree;     free(child); }  void rmv3(struct tree_node *cwd) {     struct tree_node *child = cwd -> first_child -> tree;     cwd = child -> parent;     if (strcmp(cwd -> first_child -> tree -> string_buffer, "\0") == 0) {         printf("subdirectory not empty!\n");     }     else if (cwd -> first_child != null) {         free(cwd -> first_child -> tree -> string_buffer);         free(cwd -> first_child -> tree);         free(cwd -> first_child);     } }  // implement rmdir (follow same pattern previous exercise) // *if specified directory not empty, rmdir should fail error message void do_rmdir(struct tree_node *cwd, char *arg) {      struct list_node *subdir = cwd->first_child;      // checks if user input argument null or ""     if (null == arg || !strcmp(arg, "")) {         printf("please specify directory not null: rmdir directoryname.\n");     }      while(subdir != null) {         if (strcmp(subdir -> tree -> string_buffer, arg) != 0) {             printf("directory not exist!\n");         }         subdir = subdir -> next;     }      if (strcmp(subdir -> tree -> string_buffer, arg) == 0) {          if (subdir -> tree == null) {             free(subdir);         }         while (subdir != null) {             if (strcmp(subdir -> tree -> string_buffer, arg) == 0) {                 printf("directory name exists. please provide name.\n");                 return;             }             subdir = subdir -> next;         }     } else {         printf("directory not exist!\n");     } }  int main(void) {      char directoryname[129] = "";      printf("\nprogram start... \n\n");      // getting user input string     // , capturing argument user input     char inputstring[129];     char delimiter[] = " ";     char *line;     char *arg;     struct tree_node *root = make_tree_node("root\0");     struct tree_node *cwd = root;      printf("/ >");      while (fgets(inputstring, 128, stdin)) {         inputstring[strlen(inputstring) - 1] = '\0';          // gets argument , stores arg         line = malloc(strlen(inputstring) + 1);         strcpy(line, inputstring);         arg = strsep(&line, delimiter);         arg = strsep(&line, delimiter);         //printf("your argument: %s\n", arg);          if(strncmp(inputstring, "exit", 4) == 0) {             printf("breaking...\n");             break;         }          //////////////////////////////// handling ls ////////////////////////////          else if(strncmp(inputstring, "ls ", 3) == 0) {             printf("the ls command should used without arguments.\n");         }          else if(strncmp(inputstring, "ls", 2) == 0) {             do_ls(cwd);             show_prompt(cwd);             printf("/ >");         }          /////////////////////////// handing cd (extra safe) //////////////////////////////         else if(strncmp(inputstring, "cd ..", 5) == 0) {             cwd = do_cd(cwd, root, arg);             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "cd .", 4) == 0) {             cwd = do_cd(cwd, root, arg);             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "cd ", 3) == 0) {             cwd = do_cd(cwd, root, arg);             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "cd", 2) == 0) {             cwd = root;             printf("returning root directory.\n");             show_prompt(cwd);             printf("/ >");         }          ////////////////////////////// handling mkdir /////////////////////////////////////         else if(strncmp(inputstring, "mkdir  ", 7) == 0) {             printf("please specify directory name not null: mkdir directoryname\n");             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "mkdir ", 6) == 0) {             do_mkdir(cwd, arg);             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "mkdir", 5) == 0) {             printf("please specify directory name: mkdir directoryname\n");             show_prompt(cwd);             printf("/ >");         }          ////////////////////////////// handling rmdir /////////////////////////////////////         else if(strncmp(inputstring, "rmdir  ", 7) == 0) {             printf("please specify directory name not null: rmdir directoryname\n");             show_prompt(cwd);             printf("/ >");         }         else if(strncmp(inputstring, "rmdir ", 6) == 0) {             printf("removing directory name...\n");             do_rmdir(cwd, arg);             show_prompt(cwd);             printf("/ >");         }           else if(strncmp(inputstring, "rmv", 3) == 0) {             printf("removing first child test\n");             struct tree_node *child = cwd -> first_child -> tree;             rmv(cwd);             show_prompt(cwd);             printf("/ >");         }           else if(strncmp(inputstring, "rmdir", 5) == 0) {             printf("please specify directory name: rmdir directoryname\n");             show_prompt(cwd);             printf("/ >");         }         else {             printf("unrecognised input: please try again.\n");             show_prompt(cwd);             printf("/ >");         }     }      printf("\nprogram quit... \n\n");         return 0; } 

for compiler issue such diagnostic, must trying define global variable non-constant initializer:

char *string_buffer = malloc(128 * sizeof(char)); 

this cannot done @ global level.

you must define string_buffer constant initializer such null, or no initializer @ all, have same effect, , allocate memory @ startup, in main() function:

char *string_buffer;  int main(void) {     string_buffer = malloc(128);      ... } 

note if not need reallocate string_buffer during course of program, not need make pointer dynamic memory, defining global array should suffice:

char string_buffer[128]; 

Comments

Popular posts from this blog

javascript - jQuery: Add class depending on URL in the best way -

caching - How to check if a url path exists in the service worker cache -

Redirect to a HTTPS version using .htaccess -