php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #8222 Objects are not automatically destroyed when reference count=0
Submitted: 2000-12-13 05:44 UTC Modified: 2001-04-10 09:37 UTC
From: christian dot niss at avinci dot de Assigned:
Status: Closed Package: Class/Object related
PHP Version: 4.0.3pl1 OS: Linux 2.2.16
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: christian dot niss at avinci dot de
New email:
PHP Version: OS:

 

 [2000-12-13 05:44 UTC] christian dot niss at avinci dot de
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 - %s\n",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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-03-08 12:48 UTC] stas@php.net
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.
 [2001-04-10 09:37 UTC] sniper@php.net
No feedback. If this happens with soon to be released PHP 4.0.5 too, reopen this bug report.

--Jani

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 14:01:32 2024 UTC