-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-4036] Memory leak with String.cString(using: Encoding) #3885
Comments
On investigation, I could see that String.cString() on Linux calls NSString.cString() under the covers: Further, NSString.cString() malloc's memory and returns the address of that memory to the caller: String.cString() calls _persistCString that copies the contents of this malloc'd memory into a [CChar] and returns it. We do not free the memory that was malloc'd by NSString.cString() and it's clear that malloc'd memory does not come under the purview of the ARC. Looks like we need to call `free` explicitly. |
With String.cString() we can attempt to free up the malloc'd memory after copying the contents to [CChar]. But with NSString.cString() this becomes the responsibility of the application. |
On Apple platforms the returned string is autoreleased. I think the Foundation folks just didn't have a great answer on non-Apple platforms. cc @phausler |
it is leaked; I have a prototype that would make a pseudo autorelease but that was considered to be "distasteful" 🙁 |
Comment from @parkera on the PR (which I've closed): ``` |
http://swift.sandbox.bluemix.net/#/repl/58b24367f008f226a7910246 That would be a way we could have autorelease work on linux. And the NSData backing could be done as
|
Of course the requirement for that code is that it would need to be housed in a autoreleasepool call else it would hard abort and it is worth noting that swift on linux does not have a root pool installed by default. We could at CF constructor time push a root pool and then with an atexit pop the pool. That would be a long stretch to accommodate for the handful of APIs that require autorelease behavior and it might be more reasonable to offer a new SPI:
|
That all being said: the signature `public func cString(using encoding: Encoding) -> [CChar]?` is not exactly proper since it should be a fast-path accessor if the string is eight bit represented (it should return inner pointer) and the Array<CChar> will cause an allocation as well as a full copy of the contents. |
@phausler Tested your second solution. As expected, it works well but it doesn't address the leak in NSString.cString(). |
@phausler/@parkera could we maybe deprecate |
It's still needed occasionally for things like |
I have nothing to add in terms of what the right way to fix this is, but I just wanted to call out that if this is not going to be fixed I think it should be made far more obvious that this is an issue. Deprecation, a note on the docs site, something.... would be great. I accidentally wrote some code using this method ~3 years ago when I was new to Swift and just figured out today that it's been causing memory leaks for Linux users. Because I have for the most part only developed and checked for memory leaks on macOS I never noticed it until now. |
+1, we should definitively document how you're supposed to hold this API (or deprecate it but as Jordan points out there are some (IMHO rare) usecases) |
@swift-ci create |
I think we should probably deprecate this API rather than allow it to persist with a known leak. |
Attachment: Download
Additional Detail from JIRA
md5: 342a1be011db14a8a68d02d0d35c641e
Issue Description:
This code leaks memory
The text was updated successfully, but these errors were encountered: