Thread: malloc does not seem to return

  1. #16
    Registered User
    Join Date
    Jul 2011
    Posts
    99
    Funny as the garage story may be, it does not help me a lot. I did allocate memory, and I currently I fail to see what is wrong there although I would be truly grateful if I was pointed to flaws in my reasoning. The way I see it now, I made two types of errors, one fatal and one not at all.
    The fatal error:
    Code:
    currPair = malloc(sizeof(currPair));
    The asterisk for currPair is missing, this way it sizes up the pointer, instead of what the pointer points to, the struct. Costly, time consuming mistake and thanks for pointing this out!

    Mistake type number two, statements like
    Code:
     char *key = malloc(MAXFIELD * sizeof(*key + 1));
    This shows a insufficient understanding of sizeof. Sizeof() measures the size of the type the pointer points to, but it neglects the '+ 1'. Flawed as this may be, it only boils down to a difference of 1 with the intentend difference. The '+ 1' was to be added only 1 time as a space for '\0' to terminate the string. This might have been fatal if I would have used the allocated space to the max, but this was not the case. In any case, thanks for pointing this out to me.

    For the rest, I fail to see where my reasoning is wrong. I insist a little on this, since I would like to use malloc really well. So if someone has some more detailed comments on the reasoning behind my use of malloc as I described above, it would be highly appreciated since my limited understanding of malloc (and I am not talking syntax) has already cost me a lot of time and annoyance (and a lot of your time for that matter).

  2. #17
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by django View Post
    This shows a insufficient understanding of sizeof. Sizeof() measures the size of the type the pointer points to, but it neglects the '+ 1'. Flawed as this may be, it only boils down to a difference of 1 with the intentend difference. The '+ 1' was to be added only 1 time as a space for '\0' to terminate the string. This might have been fatal if I would have used the allocated space to the max, but this was not the case. In any case, thanks for pointing this out to me.
    sizeof() returns the size of an object... on a 32 bit system sizeof(int) should return 4 ... This is the correct size to malloc...
    Code:
    #define XSIZE 100
    
    int *x;
    x = malloc(XSIZE * sizeof(int));
    ... is perfectly adequate.

    For a struct you can do this...
    Code:
    struct t_StructName
      { int x;
        int y;
        char z[100]; 
      }
    In this case sizeof(t_StructName) (the "t" just means "tag") should return the actual size of the struct so...
    Code:
    struct t_StructName *StructPtr;
    
    StructPtr = malloc(sizeof(t_StructName));
    ... is again just fine.

    I've never been a fan of the sizeof(*ptr) trick... it may return the correct value but, years later, when you have to review your code, it adds the extra step of having to figure out what ptr is pointing to... In my experience it is far less error prone (programmer error, not runtime error) to simply name the object of your current affliction.

    Malloc merely needs the correct size of the object which can come from sizeof() or for strings it can come from strlen(string)+1; +1 to allow for the trailing null. For structs and numeric variables sizeof() reports the exact size and there is no need for the +1...


    For the rest, I fail to see where my reasoning is wrong. I insist a little on this, since I would like to use malloc really well. So if someone has some more detailed comments on the reasoning behind my use of malloc as I described above, it would be highly appreciated since my limited understanding of malloc (and I am not talking syntax) has already cost me a lot of time and annoyance (and a lot of your time for that matter).
    Frankly, I think you're overthinking this by several orders... It's really no more complex than measuring the car before you build the garage...

  3. #18
    Registered User
    Join Date
    Jul 2011
    Posts
    99
    Thank you so kindly. I will try to keep it at the garage and car level.

    Let me then ask you one more question about a specific car and a specific garage....

    Suppose I have a struct like this:
    Code:
    struct someStruct {
        int someInt;
        char *somePtr;
        etc....
    }
    Now suppose I have an initialized struct, all the members have values. I want to convert to different member values to strings, concatenate them into one string (my message string) do some separators in between etc.
    If I now at runtime want to know how large my string should be, how would you figure that out? Or would simply have to know what size the different variables need, add it up and use that as the size of your string?

  4. #19
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    If you are string-izing things, then you've got some limits: an int shouldn't need more than 11 characters, for example. A char * could point to any size string, so there's no way to know ahead of time how much space you'll need until you know what your string is, and then strlen will tell you.

    If you wanted to allocate just as much space as you need and no more, then you can figure out from the value of your int how many characters it would take, from the value of your char* how much space it needs, etc.

  5. #20
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by django View Post
    Now suppose I have an initialized struct, all the members have values. I want to convert to different member values to strings, concatenate them into one string (my message string) do some separators in between etc.
    If I now at runtime want to know how large my string should be, how would you figure that out? Or would simply have to know what size the different variables need, add it up and use that as the size of your string?
    tabstop is right.... but in C there's always more than one way to skin a cat...

    Make an intermediate buffer larger than you can possibly need, use snprintf() to convert your values... the return value will tell you if it worked or not. This is a good case for a function as the buffer can be instantiated in the function and then it will be disposed of when finished...
    Code:
    struct t_MyStruct
      { int x;
        int y;
        char *z; }
      MyStruct;
    
    char *MakeString(struct t_MyStruct AStruct)
      { char Buffer[501]; 
        if (snprintf(Buffer,500, "X = %d, Y = %d  Z = %s",  AStruct.x, AStruct.y, AStruct.z) > 0)
          return strdup(Buffer); 
        else 
          return NULL; }
    
    
    // call as...
    char *String;
    
    String = MakeString(MyStruct);
    
    if (String)
      {  
         // do stuff with String
    
        free(String); }
    ... The result is a returned pointer to the space allocated by strdup(), which is the exact size of the text, not the entire size of the buffer. If the result string is too big to fit into the buffer, snprintf() returns -1 and the function returns NULL, which is your signal an error has occured and you may need to make that buffer bigger.


    Sometimes it helps to think in smaller blobs...
    Last edited by CommonTater; 08-27-2011 at 02:25 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc/free of return value
    By Bladactania in forum C Programming
    Replies: 15
    Last Post: 02-10-2009, 01:04 PM
  2. Replies: 3
    Last Post: 11-17-2008, 12:36 PM
  3. Should I cast return value of malloc?
    By movl0x1 in forum C Programming
    Replies: 12
    Last Post: 05-30-2007, 10:22 AM
  4. Replies: 6
    Last Post: 04-09-2006, 04:32 PM
  5. Return values from malloc
    By chambece in forum C Programming
    Replies: 8
    Last Post: 03-24-2006, 01:49 AM