1

Was testing some code and found an error with the following lines:

NSString *stringA = @"C99";
NSString *stringB = (__bridge id)malloc(sizeof (stringA));

It is not necessary to alloc a NSString this way, of course, and I am not required to do that. Again I was just testing on something else and I happened to stumble upon this.

The error reads:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x20)

In the console:

(lldb)

To generalize, perhaps I should ask:

Could we alloc Objective-C objects through the use of malloc?

Has someone encountered this before (which I doubt, because I don't think anyone who uses Objective-C would alloc a NSString this way), but rather than shoving it aside and call it a day, I thought I would ask and see if someone knows what the exact cause of this is and why.

Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • 1
    I have tried same but to dealoc :) , unfortunately I didnt find a way :( so if u will tell me :) – Coldsteel48 Jan 08 '14 at 22:56
  • Well, the direct cause of your error is probably that StringA is just a pointer to an NSString, so `sizeof(StringA)` is just the size of a pointer. – Chuck Jan 08 '14 at 23:18
  • @Chuck You're right with `sizeof `. I forgot mention: I had tried putting in the `type` before (i.e. `NSString`). That didn't work neither (i.e. Crash). – Unheilig Jan 08 '14 at 23:40
  • @Roma-MT Thanks, but doesn't work - `invalid operands to binary expression`. – Unheilig Jan 09 '14 at 00:31
  • 1
    The only thing I can tell it is possible I don't know how :) probably NSString has its own iVArs and properties that should also be allocated. if it was some typedef of C ofc you could cast it all as is with (void*) , if you still want to do this I think you should think about 2 things: 1)ObjectiveC allocates it using mallocs(somewhere deep inside it ofc) 2)Think very low level C language to do so. – Coldsteel48 Jan 09 '14 at 00:34
  • sizeof(stringA)*[stringA length] for previous comment. – Coldsteel48 Jan 09 '14 at 00:36
  • @Roma-MT You are right, although `malloc` return as `(void *)` already without needing to cast. Again, no-one makes me do this - I am just very curious like a kid :-) – Unheilig Jan 09 '14 at 00:38
  • there is 1 more thing: NSString is NSObject (I am not sure , not that good in objective C ) , So you should also allocate the NSObject to make that manual NSString... malloc want do this for you. – Coldsteel48 Jan 09 '14 at 00:40
  • @Roma-MT Like you - I know it is possible but just don't know how :-) – Unheilig Jan 09 '14 at 00:40
  • making an example that has 1 legit NSString allocation and profiling it in instruments allocations may help :P you will see couple of mallocs there. and it is a good beginning to see what is being allocated besides (that we don't know). – Coldsteel48 Jan 09 '14 at 00:42
  • you can check it . if alloc is triggered then it should increase the count by 1 try to disable arc and just : `NSSTring *smth;` `[smth release];' if it will work then it is :P – Coldsteel48 Jan 09 '14 at 00:47
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/44832/discussion-between-roma-mt-and-unheilig) – Coldsteel48 Jan 09 '14 at 00:48
  • @Roma-MT `stringA` is definitely alloc'ed, but `stringB` is not - because the thing crashes. – Unheilig Jan 09 '14 at 00:55
  • @Roma-MT check this (It is alloc'ed): [link](http://stackoverflow.com/questions/637022/do-nsstring-objects-need-to-be-alloc-and-init) – Unheilig Jan 09 '14 at 00:55
  • String A ofcourse allocated , it is like char* ="kqjelkqw" in C move to chat better I found some link for u – Coldsteel48 Jan 09 '14 at 00:56

3 Answers3

2

It is possible to use custom allocators for Objective-C objects. The problems with your code include:

  • NSString is a class cluster superclass (similar to an "abstract class") and cannot be instantiated on its own. You would need to use some concrete subclass of NSString. Note that the OS API does not provide any such class.
  • sizeof(stringA) is the size of the pointer variable, 4 or 8 bytes, which is too small to hold an NSString instance. You would need to use class_getInstanceSize() to compute the size.
  • +alloc performs work other than the allocation itself which is not present here. You would need to erase the memory and call objc_constructInstance().
  • ARC forbids the use of the low-level runtime functions that are needed to accomplish the above tasks.
Greg Parker
  • 7,972
  • 2
  • 24
  • 21
  • Thanks, Greg. If, for instance, I used another non-clustered object as an experiment such as `NSObject`, would that be more easily accomplishable than `NSString` or `NSArray`? Just curiosity, would there ever be a need to perform what I am trying to accomplish here in real-life situation? Thanks. – Unheilig Jan 09 '14 at 15:42
  • Non-cluster classes fix the first problem but not the other three. Only the most performance-sensitive code ever attempts to do this sort of trick. – Greg Parker Jan 10 '14 at 01:10
1

well as far as I found the closest example of allocating NSSTring Clike is like this:

 NSString* s4 = (NSString*)
 CFStringCreateWithFormat(kCFAllocatorDefault, 0, 
 (CFStringRef) __builtin___CFStringMakeConstantString("%@ %@ (%@)"),  s1, s2, s3);

ofcourse if you want to go lower and lower levels of this allocations , you should watch the CFStringRef class for its lower allocation .

but I hope this answer will satisfy you

found here, also there is more interesting things

http://www.opensource.apple.com/source/clang/clang-318.0.45/src/tools/clang/test/Analysis/NSString.m

Coldsteel48
  • 3,482
  • 4
  • 26
  • 43
0

I think the question you should be asking is what purpose that code serves.

Note that sizeof doesn't return the number of bytes in stringA, it simply returns the size of the pointer that is stringA. Who knows what lives in that little block of memory that has been allocated to stringB. Maybe it's a string, maybe not. Life is full of mystery.