Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    12

    newb questions, init array/struct, returning arrays


    1) How do I init a Struct/Array? what's the difference between these:
    STRUCT x={0}; and STRUCT x={0,5,4};

    2) Is their a way to return a string, in a function? or an array, because I am making a split() function... and I want it to return elements in an array, right now It's like this, split(string,delimeter,buffer_array), how would I get it like this, int k[] = split(string,delimeter);
    I also want to know because I want to know if you can return a char array.

    3) How would I alloc memory for an array?

    4) This isn't really a C question, it's about my IDE/compiler, msvc .NET.. When playing around with resources, I noticed that msvc kept editing them and adding things, is their any way to stop this? Like if I write my rc's with notepad and then import into msvc, it says they were not created in msvc and whatnot..
  2. #2
  3. No Profile Picture
    Senior Slacker
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Houston, TX
    Posts
    30
    Rep Power
    12
    Hi There,

    Here are some quick answers, I have to leave work soon to catch my bus.

    1) Based on your example you could do this: memset(x, 0, sizeof(x))

    2) instead of creating your own split function why not use strtok?

    3) Assuming your trying to allocate a character array using C; You could do this:
    char *my_array = (char *) calloc(array_size, sizeof(char));

    4) Not sure about this one.......

    Hope it helps a little........
  4. #3
  5. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    12
    Didn't know about strtok (thanks). But I am writing a string library [just to learn] and I am wondering how to return a char array.

    For a int array (since char is a int, same), I did this:
    Code:
    int *p=0x0; 
    p=malloc(100*sizeof(int)); //== 400 on 32b1t 
    p[0]=5;
    p[1] = 10;
    but I seen an example that type casted malloc() to (int*), and you did (char*) typecast, why is that? the way I did it worked fine.. what difference does typecasting do, sorry I need to learn :D:D

    Ok I just used strtok, how would I make my function like this? how do I return a char *?

    char* choe(char* string, const char);
    {
    return //What do I put for return?;
    }
    Last edited by movEAX_444; July 10th, 2003 at 06:11 PM.
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by movEAX_444
    1) How do I init a Struct/Array? what's the difference between these:
    STRUCT x={0}; and STRUCT x={0,5,4};
    You're doing it correctly. However, your real question is about what happens when you don't provide a value for every single field in the struct/array.

    Remember that there are basically two storage classes (I'm simplifying it here): static and auto. static variables are allocated space in RAM and that is where they stay for the duration; these are the "global" variables. auto variables are the "local" variables declared inside the functions; they are created whenever you enter the function and destroyed when you exit the function.

    Normally, static variables are automatically initialized to zero (but you shouldn't rely on that behavior. And auto variables are never initialized automatically; if you want one initialized then you have to do it explicitly.

    OK, if you do not initialize every single field of a struct/array, then the first however-many that you do give values for will be initialized and the rest will be set to zero -- I think, but I'm just not sure, that that rule applies to auto variables as well as to static variables.

    So, let's say that the struct STRUCT has three integer fields.
    STRUCT x={0,5,4}; initializes all three fields to the values in the initialization list.
    STRUCT x={0}; initializes the first field to the value in the initialization list and then initializes the remaining two fields to zero.

    That is the difference between those two definitions.

    Originally posted by movEAX_444
    2) Is their a way to return a string, in a function? or an array, because I am making a split() function... and I want it to return elements in an array, right now It's like this, split(string,delimeter,buffer_array), how would I get it like this, int k[] = split(string,delimeter);
    I also want to know because I want to know if you can return a char array.
    The basic answer is yes, but you need to be careful. Because an auto variable goes away when you exit the function, you must not return an auto variable (though you can return its value, which is something entirely different).

    Common practice is to declare the desired struct/array outside of the function and to pass a pointer to it to the function. The function then modifies that struct/array and you have use of those modifications after you return from the function. It is also common to set the function's return value to that pointer, especially in the case of char arrays so that the function can be used in an argument list.

    Examples:
    Code:
    char  s1[80];
    char  s2[80];
    
    typedef struct
    {
        int a;
        int b;
        int c;
    }  STRUCT;
    
    /* roughed-in copy of standard strcpy function */
    char *StrCpy(char* dest,const char* src)
    {
        /* copy characters from src to dest */
        return dest;  /* to allow function to appear in another function's
                           argument list */
    }
    
    void FillStruct(STRUCT *s)
    {
       /* modify the contents of s */
    }
    
    /* this one dynamically creates an array of pointers to strings and returns the pointer */
    char **Split(const char* line)
    {
        char ** sp;
    
      /* malloc an array of char* */
      /* for each token, malloc a char* and store the pointer inside the array */
      /* the tricky part will be in figuring out the size of the array 
         of char* before you've parsed the line */
        return sp;
    }
    Originally posted by movEAX_444
    3) How would I alloc memory for an array?
    C and C++ do this differently and I'm not sure which you are using.

    C uses malloc() and free(). In addition, there are a few different specialized flavors of malloc, like calloc for creating arrays. I normally just use malloc and calculate the overall size of the array:
    double *dary = (double*)malloc(sizeof(double)*ARRAY_SIZE);

    C++ uses new and delete and new[] and delete[]. The previous example would be rendered:
    double *dary = new double[ARRAY_SIZE];

    Originally posted by movEAX_444
    4) This isn't really a C question, it's about my IDE/compiler, msvc .NET.. When playing around with resources, I noticed that msvc kept editing them and adding things, is their any way to stop this? Like if I write my rc's with notepad and then import into msvc, it says they were not created in msvc and whatnot..
    I'm not using .NET and I'm not looking forward to the prospect. Especially if it keeps you from tweaking the source files. If that's the case, then why not just do it in Visual BASIC where most of the stuff is hidden from you anyway. I mean, if they are going to take away from us the advantages of using a real language, then what's the use?

    Sorry for that rant. I'm able to tweak my resource files in VC++6 and below and it doesn't complain -- just so long as I do it right. At least there the IDE clearly identifies which portions of the code are generated and maintained by it so you should keep your hands off of it. But I can tweak those parts too, just so long as I do it correctly. But if .NET won't let me do that, then I definitely don't want any part of it. I really hate it when you have to devote most of your effort to inventing ways to working around your tools -- tools are supposed to help you do your work, not create even more useless work.

    Sorry for that second rant. I'm not sure what it will take to disable that feature of the IDE. Perhaps if you create the project as non-MFC or non-.NET?
    Last edited by dwise1_aol; July 10th, 2003 at 07:16 PM.
  8. #5
  9. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    dwise<< in your above example,
    double *dary = new double[sizeof(double)*ARRAY_SIZE];
    -i was under the impression that this would be done:
    double *dary = new double[ARRAY_SIZE];
    i thought the compiler implicity calculated the size of the type and allocated teh necessary memory. or did i misunderstand your example?
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by infamous41md
    dwise<< in your above example,
    double *dary = new double[sizeof(double)*ARRAY_SIZE];
    -i was under the impression that this would be done:
    double *dary = new double[ARRAY_SIZE];
    i thought the compiler implicity calculated the size of the type and allocated teh necessary memory. or did i misunderstand your example?
    You are correct. My mistake from quickly writing in a snippet of spare time. I'll go back and correct it right now.

    Thanks!
  12. #7
  13. No Profile Picture
    Senior Slacker
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Houston, TX
    Posts
    30
    Rep Power
    12
    I agree with everything dwise1_aol said (especially the rant); the one other difference between malloc and calloc which I find nice is that calloc initializes the memory segment with all zeros malloc does not....
  14. #8
  15. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    12
    Thanks, I understand everything except [char **Split(const char* line)], I don't get the **, pointer to pointer, but I don't know how it works
  16. #9
  17. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    I don't understand the pointer to pointer either.
    I just don't understand the concept
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Basically, char** is equivalent to char* []. You can look upon it as a two-dimensional array.

    To roughly flesh Split out a bit:
    Code:
    /* just some arbitrary fixed length */
    #define MAX_ARRAY  10
    /* some dummy data */
    char *dummy[] = {"This is Line 1","And line two","and line third"};
    
    /* this one dynamically creates an array of pointers to strings and returns the pointer */
    char **Split(const char* line)
    {
        char ** sp;
        int   i;
    
      /* malloc an array of char* */
        sp = (char **)malloc(sizeof(char*)*MAX_ARRAY);
        for (i=0; i<MAX_ARRAY; i++)
            sp[i] = NULL;
    
      /* for each token, malloc a char* and store the pointer inside the array */
        for (i=0; i<3; i++)
        {
            sp[i] = (char*)malloc(strlen(dummy[i])+1);
            strcpy(sp[i],dummy[i]);
        }
    
        return sp;
    }
    
    int main(void)
    {
        char **tokens;
        char theInputLine[81];
    
        ReadInputLine(theInputLine);
        tokens = Split(theInputLine);
        if (tokens[2][1] == 'n')
            printf("Split() succeeded!\n");
    
    }
    It would have appeared a bit stranger if the pointer had been returned via the parameter list, because then we'd have had a char*** :
    Code:
    /* this one dynamically creates an array of pointers to strings and returns the pointer */
    void Split(char ***p,const char* line)
    {
        char ** sp;
        int   i;
    
      /* malloc an array of char* */
        sp = (char **)malloc(sizeof(char*)*MAX_ARRAY);
        for (i=0; i<MAX_ARRAY; i++)
            sp[i] = NULL;
    
      /* for each token, malloc a char* and store the pointer inside the array */
        for (i=0; i<3; i++)
        {
            sp[i] = (char*)malloc(strlen(dummy[i])+1);
            strcpy(sp[i],dummy[i]);
        }
    
        *p = sp;
    }
    
    int main(void)
    {
        char **tokens;
        char theInputLine[81];
    
        ReadInputLine(theInputLine);
        Split(&tokens,theInputLine);
        if (tokens[2][1] == 'n')
            printf("Split() succeeded!\n");
    
    }
    Hope that cleared things up.
  20. #11
  21. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    12
    I am playing around with malloc(), I have this so far.. but how do I put a string into the memory block I allocated? lets say I allocate 100 bytes adn want to put the string "whats up!" into that block then do printf() to show the string, how would I?

    Code:
    #include <stdio.h> 
    #include <memory.h> 
    
    int main()
    {
    
    	char c, *p=0x0, *t=0x0; 
    
    	if((t=(char*)malloc(100 * sizeof(char))) == NULL)
    	{
    		printf("Couldn't malloc\n"); 
    		exit(1); 
    	}
    	p=t; 
    	//for(c=97;c<123;c++) 
    		//*p++ = c; 
    	*p = 'h'; *++p; 
    	*p = 'e'; *++p; 
    	*p = 'l'; *++p; 
    	*p = 'l'; *++p; 
    	*p = 'o'; *++p; 
    	*p ='\0'; 
    	printf("%s\n",t); 
    	free(t); 
                    return 0; 
    }
    Last edited by movEAX_444; July 10th, 2003 at 09:20 PM.
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by movEAX_444
    I am playing around with malloc(), I have this so far.. but how do I put a string into the memory block I allocated? lets say I allocate 100 bytes adn want to put the string "whats up!" into that block then do printf() to show the string, how would I?
    There is a whole family of str* functions in string.h. You would do a string-copy with strcpy (modifying your sample code):
    Code:
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <memory.h> 
    
    int main()
    {
    
    	char c, *p=NULL, *t=NULL; 
    
    	if((t=(char*)malloc(100 * sizeof(char))) == NULL)
    	{
    		printf("Couldn't malloc\n"); 
    		exit(1); 
    	}
    	p=t; 
    
                    strcpy(p,"hello");
    	printf("%s\n",t); 
    	free(t); 
                    return 0; 
    }
    Originally posted by movEAX_444
    Also, for a string, do I do it like this (str = (char *) malloc(100))) or do I need to do 100 * sizeof(char)? dword's and such are 4 bytes, but isn't char 1 byte, so I wouldn't need the sizeof.. right
    Yes, char is one byte, so it wouldn't be necessary to use sizeof. However, there are such things as wide characters and unicode when you get into internationalization, which I haven't, so you may need to return to sizeof later.

    Another thing to consider is that you may already know the string that you want to copy over, so you can tailor the allocated memory to it:
    Code:
     
    char *str = "hello";
    char *p;
    
    p = (char*)malloc(strlen(str)+1); /* need to add one for the null terminator */
    strcpy(p,str);
  24. #13
  25. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    Can you do this?

    char *str = "hello";
    char *p;
    char *y;

    p=(char*)malloc(strlen(str)+1);
    strcpy(p,str);

    *str = "Hello again";

    y=(char*)malloc(strlen(str)+1);
    strcpy(y,str);

    printf("%s, %s", p,y);



    EDIT:
    No, you cannot. I just tried it.
    Last edited by kubicon; July 11th, 2003 at 08:46 AM.
  26. #14
  27. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    Originally posted by kubicon
    Can you do this?

    char *str = "hello";
    char *p;
    char *y;

    p=(char*)malloc(strlen(str)+1);
    strcpy(p,str);

    *str = "Hello again";

    y=(char*)malloc(strlen(str)+1);
    strcpy(y,str);

    printf("%s, %s", p,y);



    EDIT:
    No, you cannot. I just tried it.
    That's right, it won't even compile.

    Change line 8 from
    *str = "Hello again";
    to
    str = "Hello again";

    Here's what's happening. str is a pointer to char. *str dereferences str to that to which it points, namely a single character. The compilation fails because you cannot assign a char pointer to a single character.

    The basic concept to get down is that pointers and arrays are treated as almost the same thing in C. str is a pointer, but it also serves as the name of an array of characters. If we declared an array:
    char str_ary[20];
    then str_ary could also be used wherever a char* is needed. The only thing that you could not do with str_ary that you could with str would be to make it point somewhere else (I've never actually tried that, but it shouldn't work). Except for that one limitation, the two function and are used identically.

    If you can think in terms of a pointer being an array, then a pointer to a pointer should make more sense.
  28. #15
  29. pogremar
    Devshed Novice (500 - 999 posts)

    Join Date
    Jul 2003
    Location
    At Work
    Posts
    958
    Rep Power
    13
    After going over and over your "pointer to pointer" example a couple of posting up, I think I'm beggining to understand them.
    thanks oh wise1.

    Regarding this last posting. This
    char *str = "hello";
    is creating a pointer to the beginning of a literal string, right?

    so if I try do do this:
    *str = "hello again";
    Basically what I'm telling the compiler is "Hey bob, overwrite the literal string with this one" in other words "Set the value of what str is pointing to this >hello again", and the compiler says, "but is a literal, I can't do that". I'm I right so far?
    However if I do this
    str = "Hello again";
    I'm just redirecting the str pointer to point to the new literal string. The old literal string will still be there, I just won't be able to access it.

    Am I correct, sensei?
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo