Thread: Need solution for assigning char string to malloc

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    3

    Need solution for assigning char string to malloc

    I'm new in C programming, and this is my first assignment. I have completed all the coding, but there's one part doesn't seems to work.

    I actually require to build a conceptual washing machine, where I just need to inform the user about the washing mode and choice. To do this, I have created a structure for storing information about the washing details, and I assign a pointer of the structure with malloc(), so that I can free the pointer to save some power during off mode. Here's part of the code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct LogInfo                        //create new name for structure
    {
    	char DateInfo[10];
    	char TimeInfo[10];
    	char Load[25];
    	char WashMode[10];
    	char Wash[4];
    	char Rinse[4];
    	char Spin[4];
    	char Soak[4];
    	int SoakTime;
    	char Temperature[14];
    	int EstimatedTime;
    }structure;
    
    typedef structure *WashInfoPointer;           //create new type (pointer to structure)
    
    WashInfoPointer WashInfo;                     //define a pointer to structure
    
    main()
    {
    	WashInfo = malloc( sizeof(structure));        //malloc and initialize values
    	
    	WashInfo = 0,0,0,0,0,0,0,0,0,0,0; 
    
    	strcpy(WashInfo -> Load, "Small");            //Update washing details
    
    	return;
    }
    The problem is here, when it come to the last line, when it try to assign "Small" to the character array "Load".

    Are there any good solution for assigning "Small" to "Load" without disabling the "malloc"? Or are there any better solution? I have search the web for 2 days, but don't find a solution for this...

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Congratulations on writing your first program. The washing machine idea is very original .

    Now for your code :

    1) WashInfo = 0,0,0,0,0,0,0,0,0,0,0; ---- not really sure what this is supposed to do. In fact, remove it!

    2) I don't see any problem with the strcpy call.

  3. #3
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    You are clobbering your memory at the following line

    Code:
    WashInfo = 0,0,0,0,0,0,0,0,0,0,0;
    Now here is what I get when I remove this line and run your program.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct LogInfo                        //create new name for structure
    {
      char DateInfo[10];
      char TimeInfo[10];
      char Load[25];
      char WashMode[10];
      char Wash[4];
      char Rinse[4];
      char Spin[4];
      char Soak[4];
      int SoakTime;
      char Temperature[14];
      int EstimatedTime;
    }structure;
    
    typedef structure *WashInfoPointer;           //create new type (pointer to stru
    cture)
    
    WashInfoPointer WashInfo;                     //define a pointer to structure
    
    main()
    {
      WashInfo = malloc( sizeof(structure));        //malloc and initialize values
      
      /*WashInfo = 0,0,0,0,0,0,0,0,0,0,0; */
    
      strcpy(WashInfo -> Load, "Small");            //Update washing details
    
      printf("%s\n", WashInfo->Load);
      return;
    }
    [cd@localhost oakland]$ ./killua
    Small

  4. #4
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    It's not the cause of your error, but always make sure to free() allocated memory at the end of your program.

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Code:
    	WashInfo = malloc( sizeof(structure));        //malloc and initialize values
    	WashInfo = 0,0,0,0,0,0,0,0,0,0,0;
    The first one is an assignment. The second one is also an assignment (albeit non-sensical), replacing the first one. A variable can only be assigned ONE value.

    Washinfo is a pointer. I think what you meant to do here was something like this:
    Code:
    *Washinfo = {0};  // short for {0,0,0,0} etc -- this will zero out an entire array in the declaration, 
                                // and nb. it only works with 0 (this is not a declaration so it will not work anyway);
    Notice the pointer is dereferenced, so we are not assigning to it, we are assigning to where it points (the struct content). However, you can only zero a struct this way when it is declared, so that's no good anyway.

    You can do this:
    Code:
    memset(Washinfo,0,sizeof(*Washinfo));
    Notice again the de-reference in the sizeof(), since we want the size of the object pointed to (and not the size of a pointer).

    Also, look up calloc().
    Last edited by MK27; 04-20-2010 at 08:39 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    And in some indirect way, I pointed this out a few minutes ago.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by Overworked_PhD View Post
    And in some indirect way, I pointed this out a few minutes ago.
    Absolutely. It never hurts to get a few representations of something, this way if the OP does not understand me, s/he may understand you better, or vice versa. Also helps to emphasize an issue if several people point to it.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Apr 2010
    Posts
    3

    Smile

    Oh, thanks, the memset really helps in initializes the structure.

    So now, I have another array pointer to act as the washing operation control, as shown below:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    main()
    {
    	int *WashControl;                          //define array pointer for control propose
    
    	WashControl = (int*) malloc( sizeof(int[7]) );   //get 7 slots for storing interger
    
    	memset(WashControl,0,sizeof(*WashControl));     //store "load type", "wash mode", "soak"...etc
    
    
    	//after some choices were made, the back button were pressed
    	//all wash control details should be reset to 0, except "load", the first element
    
    
    	//will this work?
    
    	*WashControl[1] = 0,0,0,0,0,0;
    
    	//or how will memset work without touching the first element of the array?
    
    	free(WashControl);
    
    	return;
    }
    So lets say I have two menu, 1st: Load Menu (select load type), 2nd: Wash Menu (select wash mode etc...).

    When I push the "Back" button somewhere after "Wash Menu", it should back to "Wash Menu" and reset only related settings, without changing the load setting.

    If I were to use memset, how would I type in order for it to re-initialize the array, without bothering the first element, and without touching other element it not suppose to touch?

    lets say:

    memset( WashControl, 0, sizeof(*WashContro)l) ; //Will initialize the first element, that's not what i want

    memset( WashControl + 1, 0, sizeof(*WashContro)l) ; //Will touch 1 more element that's not belong to that array


    So how should I solve this?

  9. #9
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    Argh, I never realised that WashControl was a pointer to an int.

    Please disregard my answer, it's very late and I've written about two answers, both of which I have realised were wrong. I apologise if I mislead you.

    (The answers I am talking about are ones that I edited out, not answers from previous posts)
    Last edited by DeadPlanet; 04-20-2010 at 10:37 AM.

  10. #10
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    If I were to use memset, how would I type in order for it to re-initialize the array, without bothering the first element, and without touching other element it not suppose to touch?
    One way is to track the position. Here is an example that I came up with that doesn't use memset.

    Code:
    #include <stdio.h>
    
    #define MAX 10
    
    int main(void)
    {
      int i;
      char previous[MAX];
      char current[MAX];
    
      /*set certain elements*/
      previous[0] = 'a';
      previous[7] = 'b';
    
      current[0] = previous[0];
      current[7] = previous[7];
    
      for(i = 0; i < MAX; i++) {
        current[i] = 'c';
      }
    
      printf("The current 0 and 7 positions are: %c, %c\n", current[0], current[7]);
    
      printf("The previous 0 and 7 positions are: %c, %c\n", 
             previous[0], previous[7]);
    
    
      return 0;
    }
    [cd@localhost oakland]$ gcc -Wall -Wextra reinit.c -o reinit
    [cd@localhost oakland]$ ./reinit
    The current 0 and 7 positions are: c, c
    The previous 0 and 7 positions are: a, b
    [cd@localhost oakland]$

  11. #11
    Banned
    Join Date
    May 2007
    Location
    Berkeley, CA
    Posts
    329
    And I little bit more to the point

    Code:
    #include <stdio.h>
    
    #define MAX 10
    
    int main(void)
    {
      int i;
      char previous[MAX];
      char current[MAX];
    
      /*set certain elements*/
      previous[0] = 'a';
      previous[7] = 'b';
    
      current[0] = previous[0];
      current[7] = previous[7];
    
      printf("The current 0 and 7 positions before the loop are: %c, %c\n",
             current[0], current[7]);
    
      for(i = 0; i < MAX; i++) {
        current[i] = 'c';
      }
    
      printf("The current 0 and 7 positions are now: %c, %c\n", 
             current[0], current[7]);
    
      printf("The previous 0 and 7 positions are: %c, %c\n", 
             previous[0], previous[7]);
    
    
      return 0;
    }
    [cd@localhost oakland]$ gcc -Wall -Wextra reinit.c -o reinit
    [cd@localhost oakland]$ ./reinit
    The current 0 and 7 positions before the loop are: a, b
    The current 0 and 7 positions are now: c, c
    The previous 0 and 7 positions are: a, b
    [cd@localhost oakland]$

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by killua1234 View Post
    Code:
    	//will this work?
    	*WashControl[1] = 0,0,0,0,0,0;
    No, you can't assign to sequential elements like that. You could do this:
    Code:
    for (i=1;i<7;i++) WashControl[i] = 0;
    Since i is initially 1 this skips the first element. In other words, you always need to refer to them directly with a [subscript] (or a pointer set to such a point in the array).
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    Registered User
    Join Date
    Apr 2010
    Posts
    3
    Omg, i can't belief I forget such a simple solution my lecturer teach, even before exam...I'm doomed =="

    By the way, it works. Thanks guys, I couldn't complete my assignment without help from you guys. ^^

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The other much simpler option is to use calloc instead of malloc.
    calloc initialises the memory to all zeros.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  3. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  4. Linked List Help
    By CJ7Mudrover in forum C Programming
    Replies: 9
    Last Post: 03-10-2004, 10:33 PM
  5. Half-life SDK, where are the constants?
    By bennyandthejets in forum Game Programming
    Replies: 29
    Last Post: 08-25-2003, 11:58 AM