ID: 8222
Updated by: stas
Reported By: [EMAIL PROTECTED]
Old-Status: Open
Status: Feedback
Bug Type: Class/Object related
Assigned To: 
Comments:

If you compile PHP in debug mode (--enable-debug) does it
report any memory leaks? If not, the leak is probably not in
PHP code, but in external code (or caused by some wrong work
with external library). If yes, please post the leaks. 
Also, you could use some malloc debugging library to see if
there aren't some leaks external to PHP.

Previous Comments:
---------------------------------------------------------------------------

[2000-12-13 05:44:12] [EMAIL PROTECTED]
Hi there,

as there are no extentions returning objects, perhaps I am the first to encounter 
following problem:

I wrote an extention with functions returning objects. The problem is that these 
objects are not automatically destroyed in memory when no variable references them 
anymore.

A script like the following causes php to consume more and more memory until it 
terminates with "out of memory" ...

01:<?
02:   [...]
03:   while ($i++ < 10000)
04:   {
05:       $result=k2_searchrecv($a,$b,$c,$d,$e);
06:   }
07:   [...]
08:
09:?>

Even if I change line 05 to 
05:       k2_searchrecv($a,$b,$c,$d,$e);
so that the resulting object is not referenced by any variable, memory consumption 
grows. 

one resulting objects looks like:

object(stdClass)(9) {
  ["errorCode"]=>
  int(0)
  ["errorMessage"]=>
  string(1) "-"
  ["docStart"]=>
  int(1)
  ["docPage"]=>
  int(6)
  ["numHit"]=>
  int(6)
  ["numProc"]=>
  int(52672)
  ["numCols"]=>
  int(3)
  ["numRows"]=>
  int(6)
  ["square"]=>
  array(6) {
    [0]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(6) "401824"
      ["JOB_TITLE"]=>
      string(44) "Software-Entwickler/in Information Retrieval"
    }
    [1]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(6) "384327"
      ["JOB_TITLE"]=>
      string(18) "UNIX-Administrator"
    }
    [2]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(6) "396529"
      ["JOB_TITLE"]=>
      string(38) "SoftwareentwicklerInnen-architektInnen"
    }
    [3]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(6) "314928"
      ["JOB_TITLE"]=>
      string(27) "Anwendungsprogrammierer(in)"
    }
    [4]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(8) "10017461"
      ["JOB_TITLE"]=>
      string(41) "Praktikant oder studentischer Mitarbeiter"
    }
    [5]=>
    object(stdClass)(3) {
      ["SCORE"]=>
      string(6) "0.7742"
      ["VdkVgwKey"]=>
      string(6) "239921"
      ["JOB_TITLE"]=>
      string(38) "Internet/Intranet/Extranet-Consultants"
    }
  }
}
 
Could the problem be, that the object-type is stdClass and not a user-defined class ?

Here one function that builds an object as result:
------------------------------------------------------------
PHP_FUNCTION(k2_searchrecv)
{

        zval **shandle, **docstart, **docpage, **timeout, **fieldnames;
        zval **ksquare=0 ,***dummyzval=0 ;
        K2Error kerror; 
        char *dummyptr;
        char **fieldnamearray = 0;
        int i,j;
        int fieldcount;
        int withfieldnames = 0;
        int retries = 0;
        char *dummystring;

        K2SearchRecvOut recvOut = 0;
        K2SearchRecvArgRec recvNew;

        switch(ZEND_NUM_ARGS())
        {
                case 4: {
                        if (zend_get_parameters_ex(4, &shandle, &docstart, &docpage, 
&timeout) == FAILURE)
                                RETURN_LONG(-1);
                        break;}

                case 5: {  
                        if (zend_get_parameters_ex(5, &shandle, &docstart, &docpage, 
&timeout, &fieldnames) == FAILURE)
                                RETURN_LONG(-1);
                        withfieldnames = 1;
                        dummystring = estrdup((*fieldnames)->value.str.val);    
                        fieldcount = k2_internal_getNoOfStrings(dummystring);
                        dummyptr = dummystring;

                        fieldnamearray=(char**) emalloc (sizeof(char*) * fieldcount);
                        if (fieldnamearray == NULL)
                        {
                                php_error(E_ERROR,"k2_searchrecv: Unable to allocate 
memory for 'fieldnamearray'");
                                return; 
                        }                       

                        for (j=0; j < fieldcount; j++)
                        {
                                fieldnamearray[j]=estrdup(dummyptr);
                                dummyptr = dummyptr + strlen(dummyptr)+1;
                        }                       
                        efree(dummystring);
                        break;}

                default: WRONG_PARAM_COUNT;
        }

        convert_to_long_ex(shandle);
        convert_to_long_ex(docstart);
        convert_to_long_ex(docpage);
        convert_to_long_ex(timeout);

        K2StructInit(&recvNew);
        recvNew.docStart = (*docstart)->value.lval;
        recvNew.docPage  = (*docpage)->value.lval;
        recvNew.timeout  = (*timeout)->value.lval;

        if ((kerror=K2SearchRecv((K2Search)(*shandle)->value.lval,&recvNew,&recvOut)) 
!= K2Success)
        {
                if (kerror == 1)
                {
                        usleep(100);
                        while 
((kerror=K2SearchRecv((K2Search)(*shandle)->value.lval,&recvNew,&recvOut) != 
K2Success) &&
                                (retries < MAX_RETRIES))
                        {
                                usleep(100);
                                retries++;
                        }
                }
                if (kerror != K2Success) RETURN_LONG(kerror);
        }       
        if (object_init(return_value) == FAILURE) {
                php_error(E_ERROR, "k2_searchrecv: Unable to initialize 'return_value' 
as object");
                return -1;
        }

        add_property_long(return_value,"errorCode", recvOut->errorCode);
        if (recvOut->errorMessage) {
                
add_property_string(return_value,"errorMessage",recvOut->errorMessage,1);
        } else { add_property_string(return_value,"errorMessage","-",1); } 
        add_property_long(return_value,"docStart",recvOut->docStart);
        add_property_long(return_value,"docPage",recvOut->docPage);
        add_property_long(return_value,"numHit",recvOut->numHit);
        add_property_long(return_value,"numProc",recvOut->numProc);
        if (recvOut->square) 
        {
                add_property_long(return_value,"numCols",recvOut->square->numCols);
                add_property_long(return_value,"numRows",recvOut->square->numRows);
                
                ksquare = (zval **) emalloc (sizeof(zval*));
                dummyzval = (zval ***) emalloc(sizeof(zval**));
                *dummyzval = (zval *) emalloc(sizeof(zval *));
        
                *ksquare = (zval*) emalloc (sizeof(zval));
                if ( array_init(*ksquare) == FAILURE ) {
                        php_error(E_ERROR,"k2_searchrecv: Unable to initialize 
'*ksquare' as object");
                        return;
                }

                dummyptr = (char*) recvOut->square->pData;
                for(i=0; i < recvOut->square->numRows; i++)
                {
                        // create one element of the result list including all 
specified fields
                        *dummyzval=(zval**) emalloc(sizeof(zval*));
                        **dummyzval= (zval*) emalloc(sizeof(zval));
                        if (**dummyzval == NULL) {
                                php_error(E_ERROR, "k2_searchrecv: Unable to allocate 
memory for '**dummyzval'");
                        }

                        if (withfieldnames == 0) { 
                                if (array_init(**dummyzval) == FAILURE) {
                                        php_error(E_ERROR, "k2_searchrecv: Unable to 
initialize '**dummyzval' as array");
                                        return;
                                } 
                        }
                        else { 
                                if (object_init(**dummyzval) == FAILURE) {
                                        php_error(E_ERROR, "k2_searchrecv: Unable to 
initialize '**dummyzval' as object");
                                        return; 
                                }
                        }
                        for(j=0; j < recvOut->square->numCols; j++)
                        {
                                if (withfieldnames == 0) { 
add_next_index_string(**dummyzval,dummyptr,1);}
                                        else 
{add_property_string(**dummyzval,fieldnamearray[j],dummyptr,1);}
                                // printf("%d: %p[%d] -> %s 
n",i,**dummyzval,j,dummyptr);
                                dummyptr = dummyptr + strlen(dummyptr) + 1; 
//printf("j=%d - %sn",j,dummyptr);
                        }
                        // append 
                        
zend_hash_next_index_insert((*ksquare)->value.ht,*dummyzval,sizeof(zval*),NULL);

                }
                // append all the results in ksquare to the return structure
                
zend_hash_add(return_value->value.obj.properties,"square",strlen("square")+1, (void*) 
ksquare,sizeof (zval*),NULL); 
        } else {
                add_property_long(return_value,"numCols",0);
                add_property_long(return_value,"numRows",0);
        }

        //clean up
        K2SearchRecvFree(recvOut);
        if (withfieldnames) {
                for (i=0; i < fieldcount; i++)
                        efree(fieldnamearray[i]);
                efree(fieldnamearray);
        }
}
------------------------------------------------------------

TIA
   CHristian

---------------------------------------------------------------------------



ATTENTION! Do NOT reply to this email!
To reply, use the web interface found at http://bugs.php.net/?id=8222&edit=2


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to