I'm writing a pure C game engine. I assert every pointer returned by malloc() in my code. Now I'm writing a function that will "slice" a loaded texture into new textures (parts of the parent texture). The parent texture is loaded correctly (other textures loaded by the same loader were fine, all of them are TGA images).

I'm just going to paste the bit giving me trouble, the engine is too big.

// ...

typedef struct
{
float		W;		// Texture width
float		H;		// Texture height
unsigned char	BytesPerPixel;	// Bytes per pixel
int		Texels;		// Amount of texels
unsigned char*	TexelsPtr;	// Pointer to texels array

// ...

} CTexture;

// ...

// This is the function argument, allocated outside of the function (with an assert).
CTexture* OutputPtr;

// Other arguments and function body starts.

// Things like checking if the parent texture is big enough, etc.

// A loop body begins here

// .W, .H and .BytesPerPixel have valid values, which are given here.

OutputPtr[i].Texels = OutputPtr[i].W * OutputPtr[i].H * OutputPtr[i].BytesPerPixel;
OutputPtr[i].TexelsPtr = NULL;
OutputPtr[i].TexelsPtr = malloc(sizeof(unsigned char) * OutputPtr[i].Texels);
assert(OutputPtr[i].TexelsPtr);

// I copy the texels from parent texture here

// ... Function body ends

I get an assertion error when i == 20 (i < 96).
I checked for memory leaks with UMDH (a Microsoft tool; comes with debugging tools) and found none.

Any ideas?

Thanks

Marek

Edited 5 Years Ago by venomxxl: n/a

One thing to note is that sizeof(unsigned char) is absolutely going to return 1, every time. You can simplify the expression by removing that part.

Now, when malloc returns NULL on a modern OS, that's typically indicator of fragmented memory. You have memory to spare, but it's fragmented into small enough chunks that the memory manager can't find a large enough chunk to fulfill your request. I'd start by tracing the value of OutputPtr[i].Texels to see exactly how much memory is being requested.

You could potentially get more detailed error information by calling perror immediately after malloc.

1. Yeah, I got used to sizeof(), just a habit :P

2. In the current bit of code OutputPtr[i].Texels is always the same. The function I'm writing is going to work in 3 modes: "one rectangle, multiple textures", "one rectangle, one texture" and "multiple rectangles, multiple textures". I'm currently writing the code for first mode (I was planning to use it to "slice" an image containing monospace characters).

3. Interestingly, when I do that:

// ...

OutputPtr[i].TexelsPtr = malloc(sizeof(unsigned char) * OutputPtr[i].Texels);

if(!OutputPtr[i].TexelsPtr)
{
fprintf(Log, "strerror: %s\n", strerror_s(Buffer, 64, errno));
}

assert(OutputPtr[i].TexelsPtr);

// ...

I get a ton of access violation errors (coming from msvcr library) and a message that a stack overflow has occured. (0xC00000FD: Stack overflow.)

I thought it occured on recursions and very large variables (e.g int v[100000]).

PS. That actually should be

strerror_s(Buffer, 64, errno);
fprintf(Log, "strerror: %s\n", Buffer);

under the if-statement. Still gives errors.

Update:
I've checked the whole list of errors and the first errors come from my app. Visual Studio doesn't give a hint where that happened. Call stack contains some ntdll calls and "_error_handler4" calls (I can't see the name of the "slice" function on the list). Weird.

Edited 5 Years Ago by venomxxl: n/a

Update 2:
I didn't say one thing. The assert function is "custom", it has an another name, but to give the simple idea of what's going on I renamed it to assert() (just in this thread). When an expression is false, it fprintf's an error to my log, closes the file stream and calls exit(1). The weird errors happen after I call exit(1). Btw, strerror_s() puts "Not enough space" into Buffer.

Problem solved - there was something wrong with the loop that was copying texels. It's fixed now.

This question has already been answered. Start a new discussion instead.