I am trying to create a library that handles large integer arithmetic. Large integers are stored in the structure:
typedef struct BigInt BigInt; struct BigInt { uint32_t size; uint32_t *data; };
the first member is uint32_t, which contains the length of the number, and the second element is a pointer indicating the actual data of the number (stored in two additions). I wrote a simple toHex function (BigInt * a) that allocates memory, prints the hexadecimal value of a large integer in a string, and returns the address.
In my main loop, I have the following:
int main(int argc, char *argv[]) { char *ap, *bp; BigInt *a = fromUInt32(0x7fffffff), *b = fromUInt32(1), *c = fromUInt32(0x80000000); _add(a, b); ap = toHex(a); bp = toHex(c); printf("%s\n", ap); printf("%s\n%s\n", ap, bp); printf("%s\n%s\n", ap, bp); free(ap); free(bp); deleteBigInt(a); deleteBigInt(b); deleteBigInt(c); }
what, oddly enough, prints
0000000080000000 0 0000000080000000 0000000080000000 0000000080000000
So in the second case, printf prints something different for ap than the first and third printf expression. The first printf statement seems to be correct, and the second is messy. I went through my code with GDB and after evaluating toHex, ap points to the line "0000000080000000", terminated by a null pointer.
I am completely puzzled. As far as I can see, the possibilities are:
1. I encountered undefined behavior for some strange reason.
2. In _add, I call a procedure written in x86 assembler, it may have an error (but I adhere to the GCC calling conventions, preserving esi, edi, ebx, ebp and esp).
3. There is an error in printf that seems very unlikely.
I also have an obvious “memory leak” (a quote due to the opinion that the memory leak seems to be different for sure) without freeing up the memory allocated toHex, but that doesn't matter.
The my toHex function was requested by Sourav Ghosh and looks like this:
char numToHex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; char *toHex(BigInt *a) { char *result, *ptr;
I highlighted this strange behavior in the program ~ 100 lines of C + ~ 70 lines of assembly . Compilation can be done using
nasm -f elf -s <AssemblyName>.asm gcc <CFile>.c <AssemblyName>.o -o <OutputProgram> -m32 -std=c99 -g
The code is uncommented and designed for people who want to test the behavior for themselves.
EDIT: Ian Sterny and Matt McNabb encouraged me to use Walgrind. Valgrind says: Incorrect reading of size 1 at 0x40A5685: vfprintf (vfprintf.c: 1655) at 0x40AA7FE: printf (printf.c: 34) at 0x4075904: (below the main one) (libc-start.c: 260) Address 0x42121af - 1 byte up to a block of size 17 alloc'd on 0x40299D8: malloc (in / usr / lib / valgrind / vgpreload_memcheck-x86-linux.so) on 0x804887D: toHex (weird.c: 107) on 0x8048565: main (weird.c: 30)
But that doesn't make sense, as I set the result for malloc to toHex and didn't change anything after that. My bet now is that some records get corrupted in the build function. Edit2: After checking with GDB, I see that no registers are corrupted. I still don’t know.