On Mon, 11 Oct 1999, Uncle(Akira Watanabe) wrote:
In GrBuildPixmapFromBits(), there are two times creating of contexts; "cwork" and "result".
No. result isnŽt created. Memory for result is allocated but no frame memory is allocated:
result = (GrPixmap *)malloc(sizeof(GrPixmap)); if(result == NULL) return(NULL);
Using the auto variable cwork (allocated and destroyed automaticly on the stack) the functions creates a context where to build the Pixmap:
if (!GrCreateContext(fullw,h,NULL,&cwork)) {
Note, only the frame memory will be allocated, no memory for the context info structure since &cwork != NULL
The cwork context is now used to set up the pixmap by drawing to it.
Now the new pixmap is build:
result->pxp_source = cwork.gc_frame; result->pxp_source.gf_memflags = (GCM_MYCONTEXT | GCM_MYMEMORY);
The frame memory is passed from the cwork context to the result pixmap. Setting gc_memflags to (GCM_MYCONTEXT | GCM_MYMEMORY) marks both, the pixmap info structure (GCM_MYCONTEXT) and the frame memory (GCM_MYMEMORY) to be free()Žd by GrDestoryContext(). The frame memory is now part of the pixmap and will be returned to the user. Calling GrDestroyContext on cwork would free the frame memory.
It may look to you as if everything is alright afterwards. It really isnŽt. You introduced a reference to unallocaterd memory by passing a pointer to a free()Žd area back to the user program. Everthing works fine until the same memory block is reused. This will destroy the pattern. Calling GrDestroyPatterm on the new pixmap will lead into a second free() on this area. This results in undefined behaviour and the system may do everything it want (as someone on the GCC mailing list noted: It may even start world war III if the required hardware options are installed :(
a)"cwork" : working area for the function. User applications can not have access to "cwork" and, It isn't necessary for users to know to the "cwork" existing. So, "cwork" and the area concerned with it must be auto-destroyed at end of this function. Auto-variable"cwork" will be automatically destroyed, but "cwork->gp_pxp_source.gf_baseaddr==memory==mymem" from far heap will not be destroyed automatically.
No, as said above: The frame memory allocated from far heap is part of the pixmap.
So, this meets the above condition (B), then "memory" will be allocate from far heap. By reason of result!=&cwork, if I am willing to use GrDestroyPattern(), the apprication program can not free the local memory as "mymem"!
Please note this assignment
result->pxp_source = cwork.gc_frame;
The memory reference is returned
result -> pxp_source -> frame memory
I don't think that this problem is my poor reading of GRX documentation.
No, youŽre right. The documentation is poor.
Hope I could made it somewhat clearer ...
Hartmut