Hi, I am new to programming, I got work to remove warnings and errors thrown by swiftLint. I have resolved most of the warnings but I am stuck at one place.
let ptrOptions = UnsafeMutablePointer(&Options)
Where Options is a struture.
it is saying that it might result in a dangling pointer. How I can remove thsi?
cukr
2
the full error message is
warning: initialization of 'UnsafeMutablePointer<Options>' results in a dangling pointer
let ptrOptions = UnsafeMutablePointer(&options)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
note: implicit argument conversion from 'Options' to 'UnsafeMutablePointer<Options>' produces a pointer valid only for the duration of the call to 'init(_:)'
let ptrOptions = UnsafeMutablePointer(&options)
^~~~~~~~
note: use 'withUnsafeMutablePointer' in order to explicitly convert argument to pointer valid for a defined scope
let ptrOptions = UnsafeMutablePointer(&options)
^
it suggest a solution, which is withUnsafeMutablePointer
withUnsafeMutableBytes(of: &options) { ptrOptions in
...
}
be aware that the ptrOptions is valid only inside the closure.
@cukr i ran into same issue but in my case pointer(ptrOptions) should be variable instead of let constant any idea how i resolve this issue ?
scanon
(Steve Canon)
4
Let's back up just a little bit; what are you actually going to do with the pointer you're trying to create?
2 Likes
@scanon Thank you for replying , i have to pass that pointer to the function .
eskimo
(Quinn “The Eskimo!”)
6
i have to pass that pointer to the function.
It would help us to help you if you provided a little more info on your goals. Can you post a small snippet that illustrates the problem you’re having?
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
2 Likes
@eskimo thank you for responding
Code snippet
withUnsafeMutableBytes(of: &optionArray) { (ptrOption) -> Void in
do {
var return = try lib.function(v1: &v1.access, v2: &ptrOption, v3: &v3, v4: v4.count)
}catch{
print("Error")
}
}
Compiler is throwing dangling pointer warning , i want to remove that dangling pointer warning.
i have to pass pointer (ptrOption) to function lib.function
variable optionArray is array of C obj
Any other way i can remove dangling pointer ?
scanon
(Steve Canon)
8
What @eskimo and I are trying to get at is "what is lib.function, specifically?". The correct solution depends on that information. For instance, suppose lib.function were something like the following:
lib.h:
----
struct resultType {
int count;
option *options;
}
struct resultType function(int optionCount, option *options) {
return (resultType){ optionCount, options }
}
In a case like this, you wouldn't be able to return (or use) the result outside of the closure scoped to withUnsafeMutableBytes, because the pointer options contained in the C struct would not be valid outside of that scope.
1 Like
eskimo
(Quinn “The Eskimo!”)
9
Also, if you want more general background on this, I wrote up my experience in The Peril of the Ampersand.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
3 Likes
Nevin
10
A harrowing tale of misery and woe, set in an ancient land.
1 Like
Thanks @eskimo , i am able to remove some dangling pointer warning after reading about Ampersand .
Thank you for sharing link of The Peril of the Ampersand
lib -> lib is a struct in swift module
function -> is a method/function inside swift module structure (lib)
function does the following task :
- Open .dylib file of Clibaray
- Load Sym of the function
- Call C library function
- Return Response of that function
var optionvar = Options()
var optionArray = [optionvar] //Trying to create array
var return = try lib.function(v1: &v1.access, v2: &optionArray, v3: &v3, v4: v4.count)
When i am trying to pass optionArray it is throwing error .
Cannot convert [optionvar] to UnsafeMutablePointer<[Options]>
eskimo
(Quinn “The Eskimo!”)
12
It’s hard to say what’s going on here without more details. However, I took the code you posted and turned it into a minimal example and that works just fine:
// main.swift
var optionsArray = [Options](repeating: Options(), count: 5)
let result = gLibrary.function(&optionsArray, optionsArray.count)
optionsArray.removeLast(optionsArray.count - result)
print(optionsArray.map { $0.flag })
// printed: [100, 118, 102]
// CCode.h
#include <stddef.h>
struct Options {
int flag;
};
struct Library {
size_t (*function)(struct Options * options, size_t optionsCount);
};
extern struct Library gLibrary;
// CCode.c
#include "CCode.h"
static size_t myFunction(struct Options * options, size_t optionsCount) {
static int flags[] = { 'd', 'v', 'f' };
size_t i;
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
struct Options o;
o.flag = flags[i];
if (i < optionsCount) {
options[i] = o;
}
}
return i;
}
struct Library gLibrary = {
.function = myFunction
};
If the above example doesn’t help, I need to you reduce the problematic case to something like the above, where I can see all of the code involved.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
1 Like