0

I'm a little confused when coding an Objective-C project. The ARC is on. Here is a sample code:

NSString *foo = [[NSString alloc] initWithUTF8String:"This is a C string."];

// Use foo here...

foo = @"This is an ObjC string."

Here are my questions:

  1. Do I need to explicitly terminate C string with '\0' in initWithUTF8String: method, or it is okay to omit NULL terminator?

  2. Is there any memory leakage when I reuse foo as a pointer and assign new Objective-C string to it? Why?

  3. If I change NSString to other class, like NSObject or my own class, is there any difference for question 2? (Initialize an object and then reassign other value directly to it.)

Thank you!

mfaani
  • 33,269
  • 19
  • 164
  • 293
Zhigang An
  • 296
  • 2
  • 13
  • For your question 2: see [here](http://stackoverflow.com/questions/7071096/what-is-difference-between-mutable-and-immutable/36756871#36756871) Basically there is a new pointer created—releasing the previous pointer. – mfaani Nov 28 '16 at 21:33
  • @Honey That's a neat trick. Just print out the actual pointer with `%p`, and everything is clear. – Zhigang An Nov 28 '16 at 21:36

3 Answers3

2
  1. You must have the null terminator. From the documentation: "bytes - A NULL-terminated C array of bytes in UTF-8 encoding. This value must not be NULL."
  2. No. The compiler will insert implicit release of the previous value and retain the new one since you declared foo with (implicit) strong semantics. From the documentation: "__strong is the default. An object remains “alive” as long as there is a strong pointer to it."
  3. In general, no.
i_am_jorf
  • 53,608
  • 15
  • 131
  • 222
  • 3
    This is incorrect. Yes, the UTF8-encoded string being passed must contain a null terminator. But the compiler will implicitly null terminate a quoted literal string, which is being used here. – TomSwift Nov 28 '16 at 21:42
2
  1. An explicit \0 is not required because in C (and hence Objective C), quoted string literals are null-terminated implicitly by the compiler. Here's a similar question.

Do string literals that end with a null-terminator contain an extra null-terminator?

  1. No memory leakage. The ARC-configured compiler will generate code to release the first string that was being referenced before assigning the new string.

  2. No change. You may get a compile-time warning if the types aren't compatible.

Community
  • 1
  • 1
TomSwift
  • 39,369
  • 12
  • 121
  • 149
  • For 1, I think that's why I use non-NULL terminated cString in `initWithUTF8String:` for several years, but never run into any problem. Anyway, it is always a good practice to NULL terminate a C string. – Zhigang An Nov 28 '16 at 21:53
  • 2
    The point is that a string literal ("quoted string in code") IS NULL terminated by default. There are other ways to construct the string which would not be NULL terminated, e.g. a memcpy or initializing from a stream. – TomSwift Nov 28 '16 at 21:58
  • Okay, only string literals, like "abs". I think that's why when using `printf`, no one would write `printf("%d\n\0", 12)`. Everyone would omit the `\0` here. Thank you! – Zhigang An Nov 28 '16 at 22:04
0

For the first question, what Apple's official documentation tells me is:

Returns a string created by copying the data from a given C array of UTF8-encoded bytes.

  • (id)stringWithUTF8String:(const char *)bytes Parameters bytes A NULL-terminated C array of bytes in UTF8 encoding.

But since string literal is NULL terminated by default (as @TomSwift points out), it's okay to omit it.

Community
  • 1
  • 1
Zhigang An
  • 296
  • 2
  • 13