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 <
enrico.weig...@gr13.net> 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
> dev-platform@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-platform
>
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform

Reply via email to