On Tue, 28 Jan 2003, Ed Carp wrote: > This lef me to go back to my C textbooks (which I hadn't liiked in > almost 20 years!), and start looking for a way to figure out how to > determine how much space was allocated to a string. I was rather > surprised to find that I couldn't find such an animal! Am I missing > something here? Not really. C itself does not provide any built-in mechanism for passing sizes of buffers or other objects. Sizeof() is merely replaced with the storage size of whatever you passed to it during the compilation, and is not a runtime mechanism for determining the size of an object you point to. > I'm not interested in manual manipulation of code, or suggestions on > changing coding style - there should be a way in the language to > determine the size of an object at runtime. No. C is a fairly low-level language. There are some versions of C that generate code with range checking and such, but it's not very common (and not always as effective as in other languages). You think what made C co popular?;-) If you write your code in range checked, strong typed language, you get some strange errors all the time... if you write it in C, it runs, *maybe* sometimes behaves strangely because some variable gets overwritten, but hey, good enough to release ;-) For dynamically allocated memory, you might want to use malloc_usable_size() in glibc, or a similar mechanism available for your OS, but that works well only if the buffer is a separate chunk. It's a limited, non-portable and often dangerous approach, and most likely requires some coding style changes anyway, just to keep all buffers in separate chunks. There are several interesting ways to prevent the problem without making major changes to the code, however. One of better ideas I've seen is to register buffer sizes when buffers are created. It takes few more lines when you create an object, but this is the only effort you need to make. Buffers are later deregistered from your own free(), for heap memory - and your own function epilogue, for stack. With some help from the compiler and linker, two last steps involve no changes to your existing code. If your code uses mapped memory, you might also want to cover munmap and such. You just call register_buf() whenever you create an array, a structure or such. Its address, length and element size would be stored, so that you can query for a buffer at any time, and perhaps decide, based on element size, if its suitable for the operation you are about to perform (so that when you have a number of buffers inside an array, and you only added the array to implement index range checking, but forgot to add single buffers, your code would not overwrite other elements when modifying one, but rather bail out because of element size mismatch). The approach is not perfect, but can be quite helpful. -- ------------------------- bash$ :(){ :|:&};: -- Michal Zalewski * [http://lcamtuf.coredump.cx] Did you know that clones never use mirrors? --------------------------- 2003-01-28 00:41 --
This archive was generated by hypermail 2b30 : Tue Jan 28 2003 - 09:13:48 PST