Prev: GDAL-1.7.1 : vcvarsall.bat missing
Next: improving python performance by extension module (64bit)
From: Cameron Simpson on 30 Jun 2010 19:05 On 30Jun2010 12:19, Paul Rubin <no.email(a)nospam.invalid> wrote: | Cameron Simpson <cs(a)zip.com.au> writes: | > The original V7 (and probably earlier) UNIX filesystem has 16 byte directory | > entries: 2 bytes for an inode and 14 bytes for the name. You could use 14 | > bytes of that name, and strncpy makes it effective to work with that data | > structure. | | Why not use memcpy for that? Because when you've pulled names _out_ of the directory structure they're conventional C strings, ready for conventional C string mucking about: NUL terminated, with no expectation that any memory is allocated beyond the NUL. Think of strncpy as a conversion function. Your source is a conventional C string of unknown size, your destination is a NUL padded buffer of known size. "Copy at most n bytes of this string into the buffer, pad with NULs." Cheers, -- Cameron Simpson <cs(a)zip.com.au> DoD#743 http://www.cskk.ezoshosting.com/cs/ We had the experience, but missed the meaning. - T.S. Eliot
From: Lawrence D'Oliveiro on 30 Jun 2010 20:36 In message <mailman.2369.1277870727.32709.python-list(a)python.org>, Michael Torrie wrote: > Okay, I will. Your code passes a char** when a char* is expected. No it doesn't. > Consider this variation where I use a dynamically allocated buffer > instead of static: And so you misunderstand the difference between a C array and a pointer.
From: Michael Torrie on 1 Jul 2010 01:40 On 06/30/2010 06:36 PM, Lawrence D'Oliveiro wrote: > In message <mailman.2369.1277870727.32709.python-list(a)python.org>, > Michael Torrie wrote: > >> Okay, I will. Your code passes a char** when a char* is expected. > > No it doesn't. You're right; it doesn't. Your code passes char (*)[512]. warning: passing argument 1 of 'snprintf' from incompatible pointer type /usr/include/stdio.h:385: note: expected 'char * __restrict__' but argument is of type 'char (*)[512]' > And so you misunderstand the difference between a C array and a > pointer. You make a pretty big assumption. Given "char buf[512]", buf's type is char * according to the compiler and every C textbook I know of. With a static char array, there's no need to take it's address since it *is* the address of the first element. Taking the address can lead to problems if you ever substitute a dynamically-allocated buffer for the statically-allocated one. For one-dimensional arrays at least, static arrays and pointers are interchangeable when calling snprinf. You do not agree? Anyway, this is far enough away from Python.
From: Jorgen Grahn on 1 Jul 2010 03:09 On Wed, 2010-06-30, Michael Torrie wrote: > On 06/30/2010 03:00 AM, Jorgen Grahn wrote: >> On Wed, 2010-06-30, Michael Torrie wrote: >>> On 06/29/2010 10:17 PM, Michael Torrie wrote: >>>> On 06/29/2010 10:05 PM, Michael Torrie wrote: >>>>> #include <stdio.h> >>>>> >>>>> int main(int argc, char ** argv) >>>>> { >>>>> char *buf = malloc(512 * sizeof(char)); >>>>> const int a = 2, b = 3; >>>>> snprintf(&buf, sizeof buf, "%d + %d = %d\n", a, b, a + b); >>>> ^^^^^^^^^^ >>>> Make that 512*sizeof(buf) >>> >>> Sigh. Try again. How about "512 * sizeof(char)" ? Still doesn't make >>> a different. The code still crashes because the &buf is incorrect. >> >> I haven't tried to understand the rest ... but never write >> 'sizeof(char)' unless you might change the type later. 'sizeof(char)' >> is by definition 1 -- even on odd-ball architectures where a char is >> e.g. 16 bits. > > You're right. I normally don't use sizeof(char). This is obviously a > contrived example; I just wanted to make the example such that there's > no way the original poster could argue that the crash is caused by > something other than &buf. > > Then again, it's always a bad idea in C to make assumptions about > anything. There are some things you cannot assume, others which few fellow programmers can care to memorize, and others which you often can get away with (like assuming an int is more than 16 bits, when your code is tied to a modern Unix anyway). But sizeof(char) is always 1. > If you're on Windows and want to use the unicode versions of > everything, you'd need to do sizeof(). So using it here would remind > you that when you move to the 16-bit Microsoft unicode versions of > snprintf need to change the sizeof(char) lines as well to sizeof(wchar_t). Yes -- see "unless you might change the type later" above. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o .
From: Nobody on 1 Jul 2010 03:24
On Wed, 30 Jun 2010 23:40:06 -0600, Michael Torrie wrote: > Given "char buf[512]", buf's type is char * according to the compiler > and every C textbook I know of. No, the type of "buf" is "char [512]", i.e. "array of 512 chars". If you use "buf" as an rvalue (rather than an lvalue), it will be implicitly converted to char*. If you take its address, you'll get a "pointer to array of 512 chars", i.e. a pointer to the array rather than to the first element. Converting this to a char* will yield a pointer to the first element. If buf was declared "char *buf", then taking its address will yield a char**, and converting this to a char* will produce a pointer to the first byte of the pointer, which is unlikely to be useful. |