Arrays and Fuctions

Hi,

I have a question about creating arrays and returning pointers to them from functions. Below is some code I have to create an array:

1
2
3
4
5
6
7
8
9
10
11
12
ems::MessageProperty Manager::GetMsgProperties()
{
    ems::MessageProperty propServer = {"Instance", &m_varInstance};
    ems::MessageProperty propAlias = {"Alias", &m_varServerAlias};
    ems::MessageProperty propVisible = {"Visible", &m_varVisible};
    ems::MessageProperty *properties = new ems::MessageProperty[4];
    properties[0] = propServer;
    properties[1] = propAlias;
    properties[2] = propVisible;

    return properties;
}


And I call the code like this...

1
2
3
4
5
void Manager::SendMessage(const MsgResponse* msgResponse)
{   
    ems::MessageProperty *properties = GetMsgProperties();
    m_Publisher->SendMessage(*msgResponse, &properties);
}


At this point everything seems to be ok... but in the m_Publisher method I get an error after trying to traverse through the array. My code is below...

1
2
3
4
5
6
7
void SendMessage(const T &payload, ems::MessageProperty **ppProperties = NULL, int timeout = 0)
{
.... // left out code here
....

EmsPublisher::Message msg = m_pPublisher->CreateMessage(pBuffer, nSize, ppProperties);
}


and finally trying to actually use the array

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
Message EmsPublisher::CreateMessage(const void *payload, size_t size, MessageProperty **ppProperties)
{
    EmsPublisher::Message msg;

    CHECKED( EMS::tibemsBytesMsg_Create(&msg) );
    CHECKED( EMS::tibemsBytesMsg_SetBytes(msg, payload, static_cast<EMS::tibems_uint>(size)));

    // If there are any message properties, set them here
    if (ppProperties)
    {
    	while (*ppProperties)
    	{
    		MessageProperty *pProperty = *ppProperties++;

    		switch(pProperty->Value->Type())
    		{
			case(variant::INT):
				CHECKED( EMS::tibemsMsg_SetIntProperty(msg, pProperty->Name, pProperty->Value->Int()) );
				break;

			case(variant::LONG):
				CHECKED( EMS::tibemsMsg_SetLongProperty(msg, pProperty->Name, pProperty->Value->Long()) );
				break;

			case(variant::DOUBLE):
				CHECKED( EMS::tibemsMsg_SetDoubleProperty(msg, pProperty->Name, pProperty->Value->Double()) );
				break;

			case(variant::STRING):
				CHECKED( EMS::tibemsMsg_SetStringProperty(msg, pProperty->Name, pProperty->Value->String().c_str()) );
				break;

			case(variant::BOOL):
				CHECKED( EMS::tibemsMsg_SetBooleanProperty(msg, pProperty->Name, pProperty->Value->Bool() ? EMS::TIBEMS_TRUE : EMS::TIBEMS_FALSE ) );
				break;

			case(variant::VNULL):
			case(variant::EMPTY):
				// Message properties can't be NULL - do nothing.
				break;
    		}
    	}
    }

	return msg;
}


The first time through the loop it picks out the first property fine. However, in the 2nd iteration of the loop the pointer points to bad memory.

Can somebody help me understand what I am doing wrong here?

I know for example that if I remove the GetMsgProperties() function and change the first SendMessage function to look like below then everything works fine:

1
2
3
4
5
6
7
8
9
void Supervisor::Manager(const MsgSupervisorComponents* msgResponse)
{
    ems::MessageProperty propServer = {"Instance", &m_varInstance};
    ems::MessageProperty propAlias = {"Alias", &m_varServerAlias};
    ems::MessageProperty propVisible = {"Visible", &m_varVisible};
    ems::MessageProperty *properties[4] = { &propServer, &propAlias, &propVisible, NULL };

    m_pSupervisorPublisher->SendMessage(*msgResponse, properties);
}


Also, if I haven't provided enough information please let me know.

Many thanks for your help
Your code cannot compile. For once, Manager::getMsgProperties()'s return type is ems::MessageProperty but you are trying to return a variable of type ems::MessageProperty*.

Then in CreateMessage() you receive a pointer to a pointer, and then you iterate by advancing the pointer. This will effectively make you lose your original pointer and will therefore be unable to delete[] the memory and you will have a memory leak. You also think you'll get a NULL value for *pProperties, but you won't because the array is an array of objects, not an array of pointers to objects.
OK, yes that was a typo in the GetMsgProperties function. The header should have read as ems::MessageProperty* Supervisor::GetMsgProperties().

Thanks for pointing out the mistakes... so in the CreateMessage() function... can you suggest how I would iterate through the array correctly?

Regards
Being a C-styled array, you must also receive the number of items inside the array, or switch from an array of objects to an array of object pointers and iterate while there are valid (non-null) pointers as you are trying to do now.
Topic archived. No new replies allowed.