Quote:
Originally Posted by jpz
A few things:
1. The code in the OP is wrong. The OP code says that you are allocating enough bytes for a pointer to a pointer to a SCIP struct(i.e. sizeof(pointer to pointer to SCIP), whereas the code you just posted is calling BMS_allocMemory_call() with sizeof(SCIP). See, A is of type SCIP** (pointer to a pointer to a SCIP struct), so **A is a SCIP struct by type, so sizeof(**A) is the same as sizeof(SCIP).
|
The code in the OP was heavily bastardized, so it was probably wrong. Please ignore that, and just look at the code I posted in the 5th post.
Quote:
Originally Posted by jpz
2. I believe there is a mistake in the SCIPcreate() you posted. Assuming you want to pass it the address of a pointer to a SCIP and change the pointer that was passed to the function so that it points to a new space of memory, the line should start with *A, not A. The way it is now, all you do is change the local variable A to point to a new space of memory. When control returns to where SCIPcreate() was called, the local variable A is destroyed and you just leaked the memory you allocated in SCIPcreate().
|
You are correct. The library uses quite a lot of defines regarding function calls, and it appears I incorrectly deciphered the define statements. The code has thus been revised.
Quote:
Originally Posted by jpz
3. Here I will address print *((SCIP**)(ptr)). There are two things wrong with this. First, ptr should be a pointer to a SCIP (i.e. SCIP*). This is because you call malloc and request enough bytes for a SCIP struct. Malloc then returns the address of the first byte in the sequence of bytes it allocated for your SCIP struct. If you want to print the address of your SCIP struct, it would be print ptr. Print *((SCIP**)(ptr)) does something completely different. Casting ptr to (SCIP**) tells the compiler that the value/address stored in ptr is a pointer to a pointer to a SCIP struct. Therefore *((SCIP**)(ptr)) or *ptr reads the memory allocated by the malloc() as if it contained a pointer to a SCIP struct. But ptr actually points to a SCIP struct, so *ptr is reading the beginning of the SCIP struct you allocated as if it were a pointer to a SCIP struct. In other words, *((SCIP**)(ptr)) will printing part of the value of the first piece of data in your SCIP struct and possibly others.
|
You are very much correct. I've gone over the define statements again, and realised I misunderstood what pointer was being returned.
Quote:
Originally Posted by jpz
The second thing wrong with printing *ptr here is that *ptr points to the memory allocated by malloc. You haven't initialized that memory yet, so it will contain random values. Printing *ptr here doesn't make any sense because the old data stored in the memory you just allocated is meaningless. I think what you want to do here is print (SCIP*) ptr to print the address of the memory malloc just gave you which will be used to store a new SCIP struct.
4. SCIPcreate() never initializes the data it allocates for your SCIP struct. Since this is not done in SCIPcreate(), you will have to do it wherever you are calling SCIPcreate(). You need to initialize each member of the structure to some meaningful value. In other words, you need to set mem, set, interrupt, etc. so they point to what you want them to point to. This may mean setting them all to null, making them point to existing structures, creating new structures for them to point to, or some combination of these things. Unless you do this, all the members in your SCIP struct will contain random values.
I am fairly certain that all the values in program 1 are 0 purely by chance.
|
I realise that calling malloc simply returns a chunk of memory containing random data, and normally needs to be initialised before using. There are further function in SCIPcreate that assigns each pointer in A a block of memory to hold the struct it points to, but as my gdb print statements are made before these, I have left these out.
So, using the revised code, I am calling "print *((SCIP*)(ptr))" directly after the malloc call, with the following gdb output:
Program 1:
Code:
289 size = MAX(size, 1);
(gdb) step
284{
(gdb)
289 size = MAX(size, 1);
(gdb)
290 ptr = malloc(size);
(gdb) print ptr
$1 = <value optimised out>
(gdb) step
292 if( ptr == NULL )
(gdb) print ptr
$2 = <value optimised out>
(gdb) step
290 ptr = malloc(size);
(gdb) print ptr
$3 = (void *) 0x8338448
(gdb) print *((SCIP*)(ptr))
$4 = {mem = 0x0, set = 0x0, interrupt = 0x0, dialoghdlr = 0x0, totaltime = 0x0, stat = 0x0, origprob = 0x0, eventfilter = 0x0,
eventqueue = 0x0, branchcand = 0x0, lp = 0x0, nlp = 0x0, relaxation = 0x0, primal = 0x0, tree = 0x0, conflict = 0x0, cliquetable = 0x0,
transprob = 0x0, pricestore = 0x0, sepastore = 0x0, cutpool = 0x0}
Program 2:
Code:
289 size = MAX(size, 1);
(gdb) step
290 ptr = malloc(size);
(gdb) print ptr
$1 = (void *) 0xb7fe450c
(gdb) print *((SCIP*)(ptr))
$2 = {mem = 0x1, set = 0x8232360, interrupt = 0x1, dialoghdlr = 0xb7faa6f8, totaltime = 0x0, stat = 0xb7fe45a0, origprob = 0xb7fe4480,
eventfilter = 0xfffffffd, eventqueue = 0x1, branchcand = 0x826e6a0, lp = 0x8229c20, nlp = 0xb7fdde80, relaxation = 0x822a0d0,
primal = 0xb7f77d20, tree = 0xb7fd0f20, conflict = 0xfffffffd, cliquetable = 0x1, transprob = 0x8232360, pricestore = 0x1,
sepastore = 0x822e0b8, cutpool = 0x0}
So, I'm noticing essentially two differences. One, the memory in program 1 has been initialised somehow. Two, program 1, I think, is optimised, as shown by "print ptr" producing output "<value optimised out>" - this is not an issue, just a possible indicator for what might be causing the memory to be initialised.
The only other explanation I can think of is that the makefile for program 1 passes some sort of optimisation option to the compiler such that malloc behaves like calloc.
Edited by thealmightyone - 12/12/10 at 3:46am