depeche@quiche.cs.mcgill.ca (Sam Alan EZUST) (12/14/89)
Here is a private letter I wanted to send but it got bounced,
but I realize it should be posted publicly for some of its
content anyway.
>>> DATA
<<< 554 <john%stag.UUCP%uunet.UUCP%dynasoft@Larry.McRCIM.McGill.EDU>... Remote protocol error: Bad file number
554 john%stag.UUCP%uunet.UUCP%dynasoft@Larry.McRCIM.McGill.EDU... Service unavailable
[In message "Re: laser C question" on Dec 13, John Stanley writes:]
: [in my message I wrote:]
: > Since there is no mem.h library of routines, I use strncpy to copy the
: > contents of one-dimensional arrays.
:
: Since strncpy doesn't copy <n> bytes but rather <n> bytes OR until it
: finds the 1st null (zero) byte in the array, using strncpy to replace
: blkcpy or memcpy isn't going to work. If it has worked so-far, it's only
: because Laser C uses an incorrect implementation of strncpy or because
: you've been Very-Very lucky....
no, actually. This little fact was something I knew a little while ago
but totally forgot about until two days ago, while I was agonizing over
the strangest bug for four damned hours and finally found it after
exhausting every other goddamned possibility... Too bad your letter didn't
come two days earlier, but that's not your fault :-)..
: Moving one, two, or fifty dimensional arrays is all the same to C.
: It's just a destination address, a source address, and the number of
: bytes to move...
: I can send you one that's written for Alcyon/Sozobon C in assembly.
: It's quite fast but you'd probably have to modify it a little to be
: compatable with Lazer C. I could also send you a similar block-move
: function written entirely in C (it just wouldn't be quite-as-fast).
someone already sent me dlibs memcpy which I believe is what is used
in Sozobon.... However, I don't have an assembler and am not too
much of an expert in it anyway, so I couldn't get it installed on
my system without help.
: Alternately, does Lazer C allow copying structures using a simple
: assignment? <struct2> = <struct1>; If so, what I've ocassionaly used in
: situations like yours is to define a struct containing the array and
: moved copys of the array arround by just using assignments...
that's a good idea. I should try it. I didn't think it was possible though,
as struct names are just pointers to memory locations of data, just
like arrays, and you can address the 5th byte of a structure with
*(structname+5) just like arrays.
in reply to my using strncpy for multidimension arrays not working,
: Why won't it? Ignoring for the moment that strncpy isn't a blkcpy or
: memcpy, what's wrong with specifiying &array[0][0] as the address and
: using the size of the entire array (assuming it's smaller than 64k bytes)
: as the length?
I think I tried it and got a compiler error.. I could be mistaken, but
I passed it just
array
instead of
&(array[0][0])
since I thought the two were equivalent pointers...
: I'm trying... What you wrote makes it sound like you've been making
: some bad guesses so far so it may take a bit of work to get your program
: working the way you want it to... What are you writing anyway?
you are exactly right. However, I got it working now via the brute-force
loop-of-assign statements. If I can get dlibs installed properly on
Laser C (and I am having trouble, as you will soon see in one of
my messages posted on c-s-a-st which I posted today), I will then
translate them all into memcpy's.
: .. although, it would be a real-good-idea if you posted a note on the
: net mentioning that strncpy doesn't move <n> bytes so other beginning
: programmers who see your message won't think that it's a correct
: substitution....
ok.. I shall. Thanks for your help/reply!!
--
S. Alan Ezust depeche@calvin.cs.mcgill.ca
McGill University Department of Computer Science - Montreal, Quebec, Canada
dal@syntel.mn.org (Dale Schumacher) (12/16/89)
[depeche@quiche.cs.mcgill.ca (Sam Alan EZUST) writes...] > > [In message "Re: laser C question" on Dec 13, John Stanley writes:] [...lots deleted...] > : .. although, it would be a real-good-idea if you posted a note on the > : net mentioning that strncpy doesn't move <n> bytes so other beginning > : programmers who see your message won't think that it's a correct > : substitution.... > > ok.. I shall. Thanks for your help/reply!! > > -- > S. Alan Ezust depeche@calvin.cs.mcgill.ca > McGill University Department of Computer Science - Montreal, Quebec, Canada First, a note about strncpy(). The ANSI standard (yeah, I know, "proposed") describes strncpy() like this: The 'strncpy' function copies not more than 'n' characters (characters that follow a null character are not copied) from the array pointed to by 's2' to the array pointed to by 's1'.[121] If copying takes place between objects that overlap, the behaviour is undefined. If the array pointed to by 's2' is a string that is shorter than 'n' characters, null characters are appended to the copy in the array pointed to by 's1', until 'n' characters in all have been written. [121: Thus, if there is no null character in the first 'n' characters of the array pointed to by 's2', the result will not be null-terminated] Secondly, the dLibs version is (slightly) broken according that the above description. It only copies up to the first null character, or 'n' characters total, and does NOT pad the copy will null characters up to 'n'. This almost never causes a problem, since the destination is null-terminated in that case, but I thought I should point it out. It's also easy to fix, but I'll leave that as an exercise for the reader :-) \\ / Dale Schumacher 399 Beacon Ave. \\ / (alias: Dalnefre') St. Paul, MN 55104-3527 >< ..!nic.mr.net!bungia.mn.org!syntel!dal United States of America / \\ "The power of accurate observation is commonly called cynicism / \\ by those who have not got it." -George Bernard Shaw
kirkenda@.cs.pdx.edu (Steve Kirkendall) (12/16/89)
(I would have mailed this, but none of the machines around here have ever heard of Canada before. Or any other country either.) In article <1870@calvin.cs.mcgill.ca> depeche@calvin.cs.mcgill.ca (Sam Alan EZUST) writes: >someone already sent me dlibs memcpy which I believe is what is used >in Sozobon.... However, I don't have an assembler and am not too >much of an expert in it anyway, so I couldn't get it installed on >my system without help. Okay, here's one in C: memcpy(dest, src, count) register char *dest; /* destination address */ register char *src; /* source address */ register int count; /* number of bytes to copy */ { while (--count >= 0) *dest++ = *src++; } This can copy up to 32767 bytes at a time. It isn't very fast, though. >: Alternately, does Lazer C allow copying structs using a simple >: assignment? <struct2> = <struct1>; If so, what I've ocassionaly used in >: situations like yours is to define a struct containing the array and >: moved copys of the array arround by just using assignments... > >that's a good idea. I should try it. I didn't think it was possible though, >as struct names are just pointers to memory locations of data, just >like arrays, and you can address the 5th byte of a struct with >*(structname+5) just like arrays. No. A struct variable is not treated as a pointer. If you do something like this... struct dirent d; somefunc(d); ... then somefunc will be called with a copy of d as its argument, and the copy will be sizeof(struct dirent) bytes long, on the stack! It does *not* pass a pointer to d. Laser C can handle struct assignments. And any attempt to add an int to a struct should net you an error message. > in reply to my using strncpy for multidimension arrays not working, > >: Why won't it? Ignoring for the moment that strncpy isn't a blkcpy or >: memcpy, what's wrong with specifiying &array[0][0] as the address and >: using the size of the entire array (assuming it's smaller than 64k bytes) >: as the length? > >I think I tried it and got a compiler error.. I could be mistaken, but >I passed it just > >array > >instead of > >&(array[0][0]) >since I thought the two were equivalent pointers... They both point to the same place in memory, but they are pointers to different types of data. The first form is a pointer to an array (a vector, actually -- the first column of your two-dimensional array). The second is a pointer to a single element. The distinction isn't very important when you're using the expression as an argument to memcpy(), though. The simplest way to copy a two-dimensional array with memcpy() is: memcpy(destarray, srcarray, sizeof srcarray); Some compilers may complain about this since the first two arguments are not of type (char *). You may wish to coerce them to get rid of the warning and improve portability, at the expense of readability... memcpy((char *)destarray, (char *)srcarray, sizeof srcarray); -------------------------------------------------------------------------------- Steve Kirkendall, kirkenda@cs.pdx.edu, uunet!tektronix!psueea!jove!kirkenda
john@dynasoft.UUCP (John Stanley) (12/18/89)
[kirkenda@.cs.pdx.edu (Steve Kirkendall) writes...] > > In article <1870@calvin.cs.mcgill.ca> depeche@calvin.cs.mcgill.ca (Sam Alan EZUST) writes: >>someone already sent me dlibs memcpy which I believe is what is used >>in Sozobon.... However, I don't have an assembler and am not too >>much of an expert in it anyway, so I couldn't get it installed on >>my system without help. > > Okay, here's one in C: > > memcpy(dest, src, count) > register char *dest; /* destination address */ > register char *src; /* source address */ > register int count; /* number of bytes to copy */ > { > while (--count >= 0) > *dest++ = *src++; > } > > This can copy up to 32767 bytes at a time. It isn't very fast, though. Actualy, it can copy up to 65535 bytes if you change: while (--count >= 0) into while (count-- != 0) While the parameter passed to memcpy is usualy documented to be just an int, it's not uncommon for versions of memcpy to treat the count variable as an unsigned integer instead which doubles the amount to memory that can be moved with a single call... (Before you use this, be sure your code isn't going to have to deal with copying negative numbers of bytes... only 1/2 :^) --- John Stanley <dynasoft!john@stag.UUCP> Software Consultant / Dynasoft Systems
john@dynasoft.UUCP (John Stanley) (12/18/89)
[depeche@quiche.cs.mcgill.ca (Sam Alan EZUST) writes...] [.. responding to email I sent to him ..] > : Alternately, does Lazer C allow copying structures using a simple > : assignment? <struct2> = <struct1>; If so, what I've ocassionaly used in > : situations like yours is to define a struct containing the array and > : moved copys of the array arround by just using assignments... > > that's a good idea. I should try it. I didn't think it was possible though, > as struct names are just pointers to memory locations of data, just > like arrays, Nope. A struct name is the name of a structure. It is -not- a pointer even though it has an address that you can obtain by using: &structname (Note that the address you obtain (unless you cast it or store it into a pointer of some other type) still "knows" that it's pointing to a struct so if you use *(&structname) it references the original structure, not just the 1st byte in the structure. *(unsigned char *)(&structname) would give you the structures 1st byte... > and you can address the 5th byte of a structure with > *(structname+5) just like arrays. Nope.... *(structname+5) is an illegal construct. You can't increment a structure itself and contrary to your assumption, a structname is -not- the same as a pointer to a structure. On the other hand, ((&structname)+5) (which is different) would point to a location 5 STRUCTURES higher in memory than &structname. In C, any addition to a pointer is taken as increasing the pointer by (the value added multiplied by the size of the object being pointed at (in this case a structure)). This sometimes causes confuses because many people normaly only deal with arrarys of characters (so the sizeof object == 1). Example: struct foo { int foo_1[32][100]; }; foocpy() { struct foo src, dst; /* if your compiler allows structure assignment, */ /* the next line should copy an array 32 x 100 */ /* integers long with a single assignment... */ dst = src; /* individual elements would be referenced as... */ src.foo_1[23][7] = 2619; } > you are exactly right. However, I got it working now via the brute-force > loop-of-assign statements. If I can get dlibs installed properly on > Laser C (and I am having trouble, as you will soon see in one of > my messages posted on c-s-a-st which I posted today), I will then > translate them all into memcpy's. Good luck. You may still want to consider using struct assignments since I've been told Lazer-C does support them... > : .. although, it would be a real-good-idea if you posted a note on the > : net mentioning that strncpy doesn't move <n> bytes so other beginning > : programmers who see your message won't think that it's a correct > : substitution.... > > ok.. I shall. Thanks for your help/reply!! You're welcome... > -- > S. Alan Ezust depeche@calvin.cs.mcgill.ca > McGill University Department of Computer Science - Montreal, Quebec, Canada --- John Stanley <dynasoft!john@stag.UUCP> Software Consultant / Dynasoft Systems