memory deallocation

  • Hello,

    From what I know so far, memory allocated using the malloc() family
    of functions is freed using the free() function. Literal values such
    as :

    char *aString = "some text";

    are automatic values and are deallocated by the compiler automatically.

    When I free some pointer that was allocated as in the example
    declaration above I get a warning that a non page-aligned, non
    allocated pointer is being freed. Then in practical terms, what does a
    literal value such as a #define that is used to initialize pointers
    such as the one above serves for ?

    If for example I have a group of string #defines that are used in log
    messages, that means that I will have to malloc space for them the
    sprintf them to it, so I can be sure that I don't get that warning
    when deallocating the log messages.

    when you pass as pointer to bytes (like a void*) to cocoa (for example
    NSData), what does it do ? It copies the bytes or just copies the
    pointer ? If I pass &aString to it that means that at the end of the
    scope it will be deallocated, and NSData will have a dangling pointer ?
  • On 04 Apr 09, at 14:35, Daniel Luis dos Santos wrote:
    > Hello,
    >
    > From what I know so far, memory allocated using the malloc() family
    > of functions is freed using the free() function. Literal values such
    > as :
    >
    > char *aString = "some text";
    >
    > are automatic values and are deallocated by the compiler
    > automatically.

    This is incorrect. String constants are stored as constant data in
    your program and cannot be deallocated (because they were never
    allocated in the first place). Passing them to free() will cause an
    error like the one you observed.

    > when you pass as pointer to bytes (like a void*) to cocoa (for
    > example NSData), what does it do ? It copies the bytes or just
    > copies the pointer ? If I pass &aString to it that means that at the
    > end of the scope it will be deallocated, and NSData will have a
    > dangling pointer ?

    Depends on whether you use a NoCopy/freeWhenDone: initializer for
    NSData or not. As described in the documentation, NSData will by
    default make a copy of the data (the bytes, not the pointer).

    In your case, if you're trying to create a NSData object with the
    contents of a string, the correct usage is:

      char *cstring = "some text";
      return [NSData dataWithBytesNoCopy:cstring length:strlen(cstring)];

    We use dataWithBytesNoCopy here because the contents of the string are
    in constant data, and can be guaranteed to not change or go away.
  • On Apr 4, 2009, at 2:35 PM, Daniel Luis dos Santos wrote:

    > Hello,
    >
    > From what I know so far, memory allocated using the malloc() family
    > of functions is freed using the free() function. Literal values such
    > as :
    >
    > char *aString = "some text";
    >
    > are automatic values and are deallocated by the compiler
    > automatically.

    In actual fact, they are neither allocated nor deallocated. String
    literals are stored in a section executable itself, and the compiler
    just initializes the aString pointer have the address of that literal.

    > When I free some pointer that was allocated as in the example
    > declaration above I get a warning that a non page-aligned, non
    > allocated pointer is being freed.

    Yup, don't do that. You're attempting to free something that was never
    malloc'ed.

    > Then in practical terms, what does a literal value such as a #define
    > that is used to initialize pointers such as the one above serves for ?

    #define is a different thing altogether. The C compiler never sees
    #defines; by the time the C compiler is processing that code, all
    macros have been evaluated and that is what the C compiler sees.

    Thus, the following two things are identical as far as the C compiler
    is concerned.

    #define STR "string"
    char* str = STR;
    ---
    char* str = "string";

    > If for example I have a group of string #defines that are used in
    > log messages, that means that I will have to malloc space for them
    > the sprintf them to it, so I can be sure that I don't get that
    > warning when deallocating the log messages.

    You don't have to dealloc them, ever.

    > when you pass as pointer to bytes (like a void*) to cocoa (for
    > example NSData), what does it do ? It copies the bytes or just
    > copies the pointer ?

    It just copies the pointer.

    This is basic C (no cocoa or anything involved). I strongly recommend
    that you find a good C book that talks about pointers and how they
    work. You will save yourself years of grief and unexplained bugs if
    you understand pointers now; they are the most critical concept in C
    and if you don't understand them, you will never be a good C (C+
    +,Objective-C) programmer.

    --
    Dave Carrigan
    <dave...>
    Seattle, WA, USA
  • > If for example I have a group of string #defines that are used in log
    > messages, that means that I will have to malloc space for them the
    > sprintf them to it, so I can be sure that I don't get that warning
    > when deallocating the log messages.

    That's a symptom of a bad design. You shouldn't be trying to deallocate
    strings in code that has no idea how the strings were allocated in the first
    place. You need to have a clear idea about "ownership" of all data.

    --
    Scott Ribe
    <scott_ribe...>
    http://www.killerbytes.com/
    (303) 722-0567 voice
  • On Sat, Apr 4, 2009 at 6:02 PM, Andrew Farmer <andfarm...> wrote:
    > In your case, if you're trying to create a NSData object with the contents
    > of a string, the correct usage is:
    >
    >  char *cstring = "some text";
    >  return [NSData dataWithBytesNoCopy:cstring length:strlen(cstring)];
    >
    > We use dataWithBytesNoCopy here because the contents of the string are in
    > constant data, and can be guaranteed to not change or go away.

    This is no good. NSData will attempt to free your constant string when
    it's destroyed. You need to explicitly say freeWhenDone:NO here,
    because not specifying it is equivalent to YES.

    Mike
  • On 04 Apr 09, at 21:28, Michael Ash wrote:
    > On Sat, Apr 4, 2009 at 6:02 PM, Andrew Farmer <andfarm...>
    > wrote:
    >> In your case, if you're trying to create a NSData object with the
    >> contents
    >> of a string, the correct usage is:
    >>
    >> char *cstring = "some text";
    >> return [NSData dataWithBytesNoCopy:cstring length:strlen(cstring)];
    >>
    >> We use dataWithBytesNoCopy here because the contents of the string
    >> are in
    >> constant data, and can be guaranteed to not change or go away.
    >
    > This is no good. NSData will attempt to free your constant string when
    > it's destroyed. You need to explicitly say freeWhenDone:NO here,
    > because not specifying it is equivalent to YES.

    Erp... right you are. That last line should indeed be

      return [NSData dataWithBytesNoCopy:cstring length:strlen(cstring)
    freeWhenDone:NO];
previous month april 2009 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      
Go to today