OK, I see no flaw. I wrote a program that does the following: Varies the initial malloc() return address from 4096 to 4096 + 63. It then computes an aligned address as discussed, malloc return + 63 & ~63. I then print out the value added to address (0 - 63 to test all possible unaligned addresses), the address itself (4096 + the 0-63 value just given, then the aligned address, and the aligned address + 511 which is the range of valid addresses, and finally, the max valid address which is the original malloc() value + 63.bob wrote:I do not see how you can get an address "before" the malloc'ed memory.Chan Rasjid wrote:my free() is ok - free(memory), the original saved pointer returned from malloc().abulmo wrote:Of course you can only free what malloc returns, without masking it.Chan Rasjid wrote:I have some sort of segmentation fault, etc when the original pointer from malloc() was free()'ed - main() did not exit with a clear status 0; 2) solves the problem.Code: Select all
// 1) bug hash = malloc(hash_size + 63) & ~63; // 2) should be - hash = (malloc(hash_size + 64) & ~63) + 64;
Code: Select all
memory = malloc(hash_size + 63); hash = memory & ~63; ... free(memory); // ok free(hash); // wrong
I don't know much about hex/binary arithmetic or about address alignment. I only do what is recommended, try to align my TT start address to 64/128 bytes so that when I do multi-probe of hash at TT, TT+1,TT+2,TT+3, all 4 would be in the same cache-line.
I have to think a little about Bob's reply. I don't get it yet.
What I mean in my original post is this:
with your code above as example, the address of the block we can write to starts from 'memory'. But the address 'hash' is before the address 'memory' or hash < memory. So if we store a hash record with :
hash[0] = ...something;
that slot is outside (before) the block allocated by malloc(). This means memory corruption of some 64 bytes of data just before 'memory'.
I am not sure as I still am thinking about Bob's reply.
Rasjid
Again,Unless I am overlooking something due to a "senior moment" I don't see how that can fail. My current code can malloc() and free() things over and over as you change sides, with no problems at all...Code: Select all
mem = malloc(N+63); aligned_mem = (mem + 63) & ~63;
I'm going to write a bit of C code to check the original and aligned addresses... More in a bit...
Here's the program, first:
Code: Select all
#include <stdio.h>
void main() {
int i, mem, new;
int size=512;
int address = 4096;
printf(" inc orig align end max\n");
for (i=0; i<64; i++) {
mem = address + i;
new = (mem + 63) & ~63;
printf("%4d %4x %4x %4x %4x\n",
i, mem, new, new+size - 1, mem + size - 1 + 63);
}
}
Code: Select all
inc orig align end max
0 1000 1000 11ff 123e
1 1001 1040 123f 123f
2 1002 1040 123f 1240
3 1003 1040 123f 1241
4 1004 1040 123f 1242
5 1005 1040 123f 1243
6 1006 1040 123f 1244
7 1007 1040 123f 1245
8 1008 1040 123f 1246
9 1009 1040 123f 1247
10 100a 1040 123f 1248
11 100b 1040 123f 1249
12 100c 1040 123f 124a
13 100d 1040 123f 124b
14 100e 1040 123f 124c
15 100f 1040 123f 124d
16 1010 1040 123f 124e
17 1011 1040 123f 124f
18 1012 1040 123f 1250
19 1013 1040 123f 1251
20 1014 1040 123f 1252
21 1015 1040 123f 1253
22 1016 1040 123f 1254
23 1017 1040 123f 1255
24 1018 1040 123f 1256
25 1019 1040 123f 1257
26 101a 1040 123f 1258
27 101b 1040 123f 1259
28 101c 1040 123f 125a
29 101d 1040 123f 125b
30 101e 1040 123f 125c
31 101f 1040 123f 125d
32 1020 1040 123f 125e
33 1021 1040 123f 125f
34 1022 1040 123f 1260
35 1023 1040 123f 1261
36 1024 1040 123f 1262
37 1025 1040 123f 1263
38 1026 1040 123f 1264
39 1027 1040 123f 1265
40 1028 1040 123f 1266
41 1029 1040 123f 1267
42 102a 1040 123f 1268
43 102b 1040 123f 1269
44 102c 1040 123f 126a
45 102d 1040 123f 126b
46 102e 1040 123f 126c
47 102f 1040 123f 126d
48 1030 1040 123f 126e
49 1031 1040 123f 126f
50 1032 1040 123f 1270
51 1033 1040 123f 1271
52 1034 1040 123f 1272
53 1035 1040 123f 1273
54 1036 1040 123f 1274
55 1037 1040 123f 1275
56 1038 1040 123f 1276
57 1039 1040 123f 1277
58 103a 1040 123f 1278
59 103b 1040 123f 1279
60 103c 1040 123f 127a
61 103d 1040 123f 127b
62 103e 1040 123f 127c
63 103f 1040 123f 127d
What I am looking for, and not seeing, is any case where "align" is less than "orig" which would be bad since "orig" is the value returned by malloc. And I am lookijng for any case where "end" is greater than "max" which would be a reference beyond the end of the malloc area. I don't see either of those conditions, meaning all of my accesses are within the region I actually allocated, although they clearly don't use the first bytes except for the case where the original address is already aligned properly.
So, again, exactly what am I missing here???