You should use |forget| to transfer the ownership of the nsIArray from list
to _retval.
/* nsIArray FindRecipients (in AString name); */
NS_IMETHODIMP nsAddrBookService::FindRecipients(const nsAString & addr,
nsIArray * *_retval)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIMutableArray> list =
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (NS_FAILED(rv = FillRecipients(addr, list)) {
return rv;
}
list.forget(_retval);
return NS_OK;
}
On Wed, Aug 16, 2017 at 6:56 PM, Enrico Weigelt, metux IT consult <
[email protected]> wrote:
> Hi folks,
>
>
> I'm still a bit confused on which types (nsCOMPtr, ...) to use when
> exactly, in combination w/ IDLs.
>
> Let's consider a case where an nsArray is created and returned
> (as rval, not out-parameter):
>
> IDL:
>
> [scriptable, uuid(ea0d8b3d-a549-4666-82d8-3a82cee2a3f1)]
> interface nsIAddrBookService : nsISupports
> {
> nsIArray FindRecipients(in AString name);
> ...
> }
>
> C++:
>
> /* nsIArray FindRecipients (in AString name); */
> NS_IMETHODIMP nsAddrBookService::FindRecipients(const nsAString & addr,
> nsIArray * *_retval)
> {
> nsresult rv = NS_OK;
> nsCOMPtr<nsIMutableArray> list =
> do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
> NS_ENSURE_SUCCESS(rv, rv);
> *_retval = list;
>
return FillRecipients(addr, list);
> }
>
> I'd assume that do_CreateInstance() returns the object w/ refcnt=1.
> The assignment to nsCOMPtr should increase refcount. Correct ?
> When the function is left, the nsCOMPtr is destroyed, and refcnt
> goes back to 1 (we now have a reference left in the caller's pointer
> field).
>
> Now the caller side: (inspired by various examples ...)
>
> nsCOMPtr<nsIArray> list;
> rv = addrBookService->FindRecipients(
> splittedRecipients[j].mEmail,
> getter_AddRefs(list));
>
> I'd guess getter_AddRefs() causes refcnt to be increased again, so
> we're back at 2. That could lead to a leak, when that function returns
> (and doesn't pass the ref anywhere else).
>
> So, should I use dont_AddRef() here ?
>
> Is the situation different when using out parameter instead of rval ?
>
> BTW: what happens when passing nsCOMPtr as a reference (w/o IDL) ?
>
> Assume the following code:
>
> void caller() {
> nsCOMPtr<nsIFoo> ref;
>
> callee(ref);
> ref->Something();
> }
>
> void callee(nsCOMPtr & outref) {
> nsCOMPtr<nsIFoo> myref = do_CreateInstance(...);
> ...
> outref = myref;
> }
>
> I'd assume that the last line will fill the caller's ref field w/ the
> pointer and increase the object's refcnt (so it's 2 now), then when
> callee is left, its myref is destroyed and refcnt is back to 1.
>
> Is that correct ?
>
>
> --mtx
>
> _______________________________________________
> dev-platform mailing list
> [email protected]
> https://lists.mozilla.org/listinfo/dev-platform
>
_______________________________________________
dev-platform mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-platform