I am having trouble correctly allocating memory for a parent function that will remain upon the child functions exit.

the call to the child function is

HTTP_packToGen((char*)http_headerContent.HTTP ..

the HTTP variable within http_headerContent is a char pointer that isn't allocated until the child function is called, http_headerContent is a static struct.
The following is called within HTTP_packToGen which is the child function

if (hdrContent == NULL)
{
	hdrContent = (char*)malloc((strlen(command)+strlen(data)+sizeof(bool))+4);
	memset(hdrContent, '\0', sizeof(*hdrContent));
}

Recommended Answers

All 9 Replies

Your code to clear the contents of the hdrContent variable is wrong, and won't clear the entire allocated space. This is a case where calloc() is a better option than malloc(), as it allocates and clears the memory at the same time. The calloc() function takes two arguments: the first is the number of elements, and the second is the size of each element.

So, your allocation code would be something like this:

hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeof(char));

Also, make sure you have allocated enough space for a terminating null byte.

commented: This fixed future bugs in my code, thank-you. +1

Your code to clear the contents of the hdrContent variable is wrong, and won't clear the entire allocated space. This is a case where calloc() is a better option than malloc(), as it allocates and clears the memory at the same time. The calloc() function takes two arguments: the first is the number of elements, and the second is the size of each element.

So, your allocation code would be something like this:

hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeof(char));

Also, make sure you have allocated enough space for a terminating null byte.

Thank-you for that I didn't know about that function, removes the need for memset immediately after the allocation.

problem is I'm still having the problem where the calling function cannot access the data the child function created and yet the pointer is within a global struct, I'm missing something here. I can't understand how it appears the child function creates the pointer as local within a pointer provided from the parent function.

Well, without seeing what the rest of your code looks like, I can only make some uneducated guesses. One thing to look for is variable overloading. That is when you have a global variable defined somewhere, and yet somewhere else, in a header or in your source file, there is another variable of the same name. For example, if you declared/define a variable in your local translation unit, or local function, with the same name as an external global variable, the local one would take precedence and the global one would not be modified.

what I think is happening is that

hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeof(char));

is replacing the variable pointed to by the call

packToGen(char *hdrContent, char *pTempBuf, char *bufTemp, int szBufTmp, int x, char *message, ...)

I want to know how I can allocate the memory for the variable pointed to by the call to packToGen without replacing the pointer with another pointer.

Yes, that would result in a problem. You need to change the hdrContent argument to be a char**, and pass the address that holds the pointer. Then, you probably also need to free the old memory. So, maybe something like this is appropriate:

if (hdrContent == 0)
{
    /* Error - invalid argument */
}
else if (*hdrContent != 0)
{
    free(*hdrContent);
}

*hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeoof(char));

Yes, that would result in a problem. You need to change the hdrContent argument to be a char**, and pass the address that holds the pointer. Then, you probably also need to free the old memory. So, maybe something like this is appropriate:

if (hdrContent == 0)
{
    /* Error - invalid argument */
}
else if (*hdrContent != 0)
{
    free(*hdrContent);
}

*hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeoof(char));

When I implement that code it says "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

Well, without seeing the calling code and called code completely, this is hard to nail down. Until then, nothing is cast in concrete...

The calling code

pTempBuf = HTTP_packToGen(&http_headerContent->HTTP, pTempBuf, bufTemp, sizeof(bufTemp), x, "HTTP/1.1 %d %s\r\n", http_htmlheaderStatus[x].code, http_htmlheaderStatus[x].string);

the called code is

char* HTTP_packToGen(char **hdrContent, char *pTempBuf, char *bufTemp, int szBufTmp, int x, char *message, ...)
{
        va_list ap;
	char tmpbuf[1024];
	int colonPos = 0;
	char command[32], data[256];
	bool httpGet = FALSE;
	memset(tmpbuf, '\0', sizeof(tmpbuf));

	va_start(ap, message);      // Initialize the va_list.

        vsnprintf(tmpbuf, sizeof(tmpbuf), message, ap);
	if (strstr(tmpbuf, ":") != NULL)
	{
		httpGet = TRUE;
	}
	sscanf(tmpbuf, "%s %{%512s}", command, data);
	//MessageBoxA(0, data, command, MB_OK);

	pTempBuf += _snprintf(pTempBuf, szBufTmp - (strlen(bufTemp) - 1), "%s%s%s", command, httpGet ? ": ":" ", data);

	*hdrContent = (char*)calloc((strlen(command)+strlen(data)+sizeof(bool))+4, sizeof(char));
	
	_snprintf(*hdrContent, (strlen(command)+strlen(data)+sizeof(bool))+4, "%s %s", command, data);
	output("httpGenerate.cpp", "HTTP_packToGen", "%s", *hdrContent);
	return pTempBuf;
}

I have been testing other parts of the code and the

if (hdrContent == 0)
{
    /* Error - invalid argument */
}
else if (*hdrContent != 0)
{
    free(*hdrContent);
}

kept causing crashes where Visual Studio would show me some code written by microsoft some output.c file and it didn't really help me work out what was causing the issue so I removed the tests and the free(... call

Thankyou for you help I have discovered the problems cause. It wasn't anything to do with the code I posted prior it was further down in another call to the same packing function

if (location != NULL)
	{
		pTempBuf = HTTP_packToGen(&http_headerContent->location, pTempBuf, bufTemp, sizeof(bufTemp), x, "Location: %s\r\n", location);
	}

AND

if (content_length != 0)
	{
		pTempBuf = HTTP_packToGen(&http_headerContent->content_length, pTempBuf, bufTemp, sizeof(bufTemp), x, "Content-Length: %d\r\n", content_length);
	}

I have fixed it so it sets the pointers to NULL so it doesn't cause the _snprintf function to when accessing them flag a permission failure and crash the program.

Again thank-you alerting me to the misuse of malloc and pointing me to calloc.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.