HDTenEightyP/NetNews huggingface dataset:
From: dljarvis@lynx.cat.syr.edu (David Jarvis)
Newsgroups: comp.lang.c,comp.unix.programmer
Subject: strange memory problem
Date: 6 Nov 92 15:53:07 GMT
Organization: Syracuse University

I'm having a strange memory problem (or perhaps it's strange because
of my lack of expertise), and can't seem to track it down.  The reason
I can't track it down is because:  (in an abbreviated version) 

main ()
{
	printf ("this gets printed\n");
	my_function (arg);
	printf ("this does not\n");
}

my_function (int arg)
{
	/* do some stuff */
	printf ("this gets printed\n");
}

So ... I see the program going _into_ the function, I see the function
execute and tell me when it's about to return to main, but I never see
the return message in main!  Could someone offer some insights into
how I might track down such a problem (or better yet what it might be?! :-))?
(quick responses are *greatly* appreciated, I can't take no more
sleepless nights in front of this terminal! :-) )
oh btw: this is on SCO Xenix ver 2.3.4, with SCO dev/sys ver 2.3.1, using
GNU's gcc ver 1.40
Please respond directly via email to david@dynamix.com 
(or dljarvis@cat.syr.edu) and if there is sufficient interest
I could post the summary to the net.

many thanks
/david
david@dynamix.com
Newsgroups: comp.lang.c
Subject: a question on function returning a pointer to a function
From: mlevin@husc8.harvard.edu (Michael Levin)
Date: 10 Nov 92 12:29:52 EST
Distribution: usa
Organization: Harvard University Science Center

     What is wrong with the following piece of code (at compile-time)?

int a(int p); 
int b(float p);

int (*which_funct(s))()
char *s;
{
  if (!stricmp(s,"A"))
    return(a);
  if (!stricmp(s,"B"))
    return(b);
}

cc (on a Sun) doesn't complain at all. Neither does VAX-11 C. gcc
however gives an error about the last line (line 10) - incompatible
types. I've been told that it is because I didn't specify (in the
definition of which_funct()) what type of argument the function to
which I'm trying to return a pointer takes. But, what if I want to
return functions which take different arguments, like in the above
example? I want which_funct() to return a pointer to either function
A, which takes an int, or function B, which takes a float. What should
the syntax look like? Please reply to mlevin@husc8.harvard.edu.

Mike Levin
From: mikey@ontek.com (euphausia superba)
Newsgroups: comp.lang.c
Subject: Re: To Recurse or NOT to recurse?
Date: 9 Nov 92 18:26:19 GMT
Organization: Ontek Corporation -- Laguna Hills, California

In comp.lang.c, sjs@netcom.com (Stephen Schow) writes:
| What is better to do when traversing a linked list..... SHould I use recursion
| to search down through the list for the last node, or should I use a while
| loop?  What or the pro's and con's of each?

I've seen several replies so far to the above which answer a more
general question than Mr. Schow asked.  The "best" solution in terms of
minimizing execution speed and stack space is to maintain a pointer to
the last item on the list; then no search is necessary.  The only
additional costs are that the (probably only one) function that adds
things to the list needs to update the pointer (which is a trivial
operation at that point) and the extra pointer.

       the krill

Xref: sparky comp.lang.c:16083 comp.software-eng:4183 comp.sys.mac.programmer:18082
From: pebi@aem.umn.edu (Peter A. Bidian)
Subject: Q: Structures, arrays, malloc and free...
Organization: University of Minnesota
Date: Wed, 11 Nov 1992 15:21:12 GMT


Hi!

Sorry to use all that bandwidth, but I have a problem that drives me
bonanza...

I define matrices as structures:


	struct matrix{
		unsigned rows;
		unsigned cols;
		double **elem;
		};

Using in a header these definitions, I assign memory to the arrays in the
definition:

	double **memmat(unsigned, unsigned);
	void freemat(struct matrix);

This is a function that initializes the matrix.

	struct matrix matdef(unsigned rows, unsigned cols)
	{
		struct matrix m;
	
		m.rows=rows;
		m.cols=cols;
	
		m.elem=memmat(m.rows,m.cols);
	
		return m;
	}


This all works well. But the problem starts, when I try to free all these
allocated matrices. I use the freemat above as a call to free a certain
matrix, in fact only its array **elem asigned before. That is:


	void freemat(struct matrix m)
	{
		int i;

		for (i=m.cols-1; i>=0; i--) free((char*) m.elem[i]);
		free((char*) m.elem);
	}
	
This doesn't seem to work at all. I get buss errors and so on. I tried
to change the (char *) to (double *), or let it go alltogether. I tried
to pass the matrix m as a pointer to it in freemat.... nothing worked.

Does anybody have any suggestions? I would be thankfull if you could 
reply by mail. I don't know of how much interest this is for the general
public. .... And another point to this topic. If I have a function that
adds to matrices and returns the result: I define the resulting matrix
in the function as above. My question is: every time I call the function
will this definition allocate more and more memory, or will it work on the
same chunk of memory. I.e. if I call that function 200 times, will
the program allocate finally 200 different chunks of memory of that
size, or will it use a earlier chunk.

Thanks a lot,

Peter

... hoping to recover from "sleepless" nights... :-)



Newsgroups: comp.lang.c
From: dfuller@portal.hq.videocart.com (Dave Fuller)
Subject: Re: Returned struct
Organization: VideOcart Inc.
X-Newsreader: Tin 1.1 PL3
Date: Fri, 6 Nov 1992 00:04:26 GMT

sl14@crux3.cit.cornell.edu (Stephen Lee) writes:
: How can one make use of a struct returned by a function?  e.g.
: 
: struct complex complex_add(struct complex a, struct complex b);
: 
: I tried
: 
: struct complex z1, z2, z3;
: 
: z1.x = 0; z1.y = 3;
: z2.x = 5; z2.y = 4;
: 
: z3 = complex_add(z1, z2);
: 

  If indded you want to use a return value, it should exist as a pointer
to the structure (which is either static or malloc'd, both are messy)
secondly, passing structures around is not the right way to deal
with them, you need to pass them as pointers. Although some compilers
allow passing of structures, lets assume it will end up on one that 
doesn't do this.

try int complex_add(struct complex *a, struct complex *b, struct complex *c)
then call it as complex_add(&z1, &z2, &z3)

then in it the routine do this 

int complex_add(. . .definitions again . . .)
{
   c->x = a->x + b->x;
   c->y = a->y + b->y;
   .
   .
   or whatever you want to do with the members
   .

   return 0;
}


As i said, you can pass structures with some compilers, but if you want 
to do this the 'right' way, pass the pointers to them instead.

Dave Fuller
dfuller@portal.hq.videocart.com
Newsgroups: comp.lang.c
From: cs460129@ucs.usl.edu (Martinez Velez Jose Carlos)
Subject: HELP ON C BOOK
Organization: Univ. of Southwestern La., Lafayette
Date: Sat, 7 Nov 1992 02:09:47 GMT

I'm trying to learn c and I wonder if anyone out there knows a good to 
learn c. I already know pascal and modula-2, so if anyone knows of a book
relating any of this language to c, please sent me e-mail...


       E-mail: cs460129@ucs.usl.edu
                      or
                  fjl0014@usl.edu


Newsgroups: comp.lang.c,comp.lang.c++
From: jmolinari@hamp.hampshire.edu
Subject: Re: *** IMPORTANT DISCOVERY ***
Organization: Hampshire College
Date: Fri, 13 Nov 1992 22:39:56 GMT

In article <1992Nov13.210911.3086@msuinfo.cl.msu.edu>, knaggs@cps.msu.edu (Scott A Knaggs) writes:
> "Will you do anything for me?", I asked. "Yes", was your answer. I asked you
> to lay down. You did. I squated right above your head and again, your tongue
> started to do it's job. You heard me make a strange noise: "NNNNNNGGGGG".
> You thought it was my extasy, but you soon found out it was something else.

[and more even worse stuff]

	I don't know wether to laugh, cry, or wonder if I've been
missing out on something.


Newsgroups: comp.lang.c
From: sasghm@theseus.unx.sas.com (Gary Merrill)
Subject: Re: constant-expression
Originator: sasghm@theseus.unx.sas.com
Date: Tue, 10 Nov 1992 17:31:40 GMT
Organization: SAS Institute Inc.


In article <0E010598.ia94k0@kithrup.Irvine.CA.US>, nagel@kithrup.Irvine.CA.US (Mark D. Nagel) writes:
|> I checked the FAQ and found not a clue to the following question.
|> 
|> Given an array declaration like:
|> 
|> const int foo[] = { 1, 45, 67, 4 };
|> 
|> why is the following code rejected (it is in MSC 6.0 at least)?
|> 
|> switch (integer_variable)
|> {
|> 	case foo[2]:
|> 		...
|> 		break;
|> 
|> 	...
|> }
|> 
|> I gather that the ANSI standard says that the indexing operation makes
|> the expression not a constant-expression, but it seems that a compiler
|> should be able to deal with this.  I could understand if the case
|> contained something like foo[i], but it doesn't.
|> 
|> 
|> -------------------------------------
|> Mark Nagel <nagel@mdn.uucp>
|> 
|> If at first you don't succeed, that's pretty much it.
|> 				-- SDI Design Team

Sure, in the specific (type of) case that you provide in the example,
a compiler could do something reasonable.  But why bother?  First,
the implementation of the appropriate action in a code generator would
not be a particular instance of a general code generation strategy
since you can't do it when you don't have access to the array and
its initialization in terms of constants.  Think of how (if you
were writing the language standard) you would phrase the constraint
on case values to permit just the sort of thing you have in mind
here but prohibit pathological cases.

Second, the above is an example of genuinely silly code.  The
language has a fairly nice mechanism for what you are trying to
accomplish by means of your perversion:  its called an *enumeration*.
-- 
Gary H. Merrill  [Principal Systems Developer, C Compiler Development]
SAS Institute Inc. / SAS Campus Dr. / Cary, NC  27513 / (919) 677-8000
sasghm@theseus.unx.sas.com ... !mcnc!sas!sasghm
From: martelli@cadlab.sublink.org (Alex Martelli)
Newsgroups: comp.lang.c
Subject: Re: Unix C Guru NEEDED!
Date: 3 Nov 92 15:33:47 GMT
Organization: CAD.LAB S.p.A., Bologna, Italia

richard@crowded-house.den.mmc.com (Richard Armstrong) writes:

:Thanks to the many people who took the time to explain the problem with the
:function I inherited. This is a fantastic group! 
:
:The problem with the code, was that the result string was created as an
:automatic character string in the lowest called function. The pointer to
:that string was passed up as return values to each function that manipulated
:it. Since the string was created on the stack, the string would be corrupted
:as functions were returning, and others were called. 
:
:The four solutions to the problem were: 
:
:1) Create the string as a static in the function so the pointer to it
:   and the string would remain "static".
:
:2) Create the result string as a global, and don't pass it around.
:
:3) malloc the string in the function that creates the string, and pass the
:   pointer to it around. (have to worry about freeing it sometime)
:
:4) Create the string in main, and pass the pointer to the functions that
:   manipulate it. (this is how I normally write this type of function).

Analysis and suggestions perfectly correct.  I just want to suggest a 
further dirty trick that can alleviate some problems when porting code
written according to suggestion 1).

The worst problem with 1), as some have suggested, is that often people
will NOT properly strcy() the returned string before calling the
function again, eg if you have...:

char *
thefun(int some_arg)
{
    static char local[16];
    sprintf(local,"{%d}",some_arg);
    return local;
}

then some call such as printf("%s %s\n", thefun(anarg), thefun(another))
will cause trouble.
The only way to PERMIT such calls (presumably just as long as you get
around to clean up the code all around...) is the dirty trick I was
speaking about, something on the lines of:

#define MAX_SIMULTANEOUS_OUTSTANDING_CALLS 16
char *
thefun(int some_arg)
{
    static int current_call;
    static char local[16][MAX_SIMULTANEOUS_OUTSTANDING_CALLS];

    if(++current_call>=MAX_SIMULTANEOUS_OUTSTANDING_CALLS)
	current_call=0; /* wraparound */
    sprintf(local[current_call],"{%d}",some_arg);
    return local[current_call];
}

Yes, it IS still filthy (filthier than the simpler static version above,
given it violates the principle about the only numbers making sense
being 0, 1, and infinity...), but sometimes it does come in handy
temporarily.
(I'll even admit to having ONE function *built* on this design - a thingy
called debug_string() which takes in a char*, returning a pointer to
a string "(NULL)"  if its arg is 0, else to the first up-to-40 chars or so
of it formatted to show control characters in a form such as "^G", etc - 
designed for quick-and-dirty printf()'s [or invocation from inside a
debugger]...).
-- 
Email: martelli@cadlab.sublink.org                   Phone: ++39 (51) 6130360
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia   Fax: ++39 (51) 6130294 
Newsgroups: comp.lang.c
From: sl14@crux3.cit.cornell.edu (Stephen Lee)
Subject: Returned struct
Organization: Fantasy Zone Ithaca, Inc.
Date: Thu, 5 Nov 92 07:56:11 GMT

How can one make use of a struct returned by a function?  e.g.

struct complex complex_add(struct complex a, struct complex b);

I tried

struct complex z1, z2, z3;

z1.x = 0; z1.y = 3;
z2.x = 5; z2.y = 4;

z3 = complex_add(z1, z2);

But BC++ 2.0 complained 'illegal structure operation' on the above.
Note:  I'm using C, not C++.

Please help me..  AdTHANKSvance,
--
Stephen Lee
Internet: sl14@crux2.cit.cornell.edu
From: msb@sq.sq.com (Mark Brader)
Subject: Re: Memory functions  -  memcpy & memmove
Organization: SoftQuad Inc., Toronto, Canada
Date: Sun, 8 Nov 92 22:54:40 GMT

In the second-last-referenced article, we have:

> Write your own memmove (different name of course). ...
> Let's say you call it  moveit(char * dest, char *source, int size)

[Part of it reads:]

> for(size --; size >= 0; size --)
>   dest[size] = source[size];

These parts of the code are correct as far as they go, but they do not
provide a correct emulation of ANSI C's memmove().  The actual argument
types of memmove are (void *, const void *, size_t).  The variations
in the first two arguments don't matter here, but the third one does.

In ANSI C, size_t is guaranteed to be an unsigned type.  (Note: this
is not true on some pre-ANSI implementations that provide size_t!)
moveit() should be able to move as many bytes as the implementation
allows in an object, and its third argument should be either unsigned
or unsigned long (if you don't have a size_t type that is one or the
other, you'll have to guess which).

Once you have made this change, the above loop is now unsafe; it fails
badly if size==0 initially.  The easy fix is to change the for-header to:

	while (size-- > 0)	/* or != 0, according to taste */

For another issue of concern, see the last-referenced article, another
followup to the same base article, by Dave Eisen.
-- 
Mark Brader			"It's simply a matter of style, and while there
SoftQuad Inc., Toronto		 are many wrong styles, there really isn't any
utzoo!sq!msb, msb@sq.com	 one right style."	-- Ray Butterworth

This article is in the public domain.
Newsgroups: comp.lang.c
From: ungar@leland.Stanford.EDU (Jeffrey Ungar)
Subject: Re: Reasons for using C vs. Fortran or vice/versa
Organization: DSG, Stanford University, CA 94305, USA
Distribution: usa
Date: Fri, 13 Nov 92 07:55:06 GMT

In article <1992Nov13.060701.6917@u.washington.edu> rons@hardy.u.washington.edu (Ronald Schoenberg) writes:
>
>The most important matrix operation in numerical work is the gaxpy
>("generalized a times x plus y").  Numerical routines are written to
>be rich in gaxpies (see Matrix Computations by Golub and Van Loan for

[misleading(?) stuff about column vs. row major order deleted]

>
>#include <stdio.h>
>
>void main()
>{
>    float a_col[] = { 1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16 };
>    float a_row[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
>    float x[] = { 1,2,3,4 };
>    float z[4];
>
>    int m = 4, n = 4;
>    int i, j, k;
>
>/*
>** column echelon gaxpy
>*/
>    for (i = 0; i < m; i++) {
>        z[i] = 0;
>        k = i;
>        for (j = 0; j < n; j++) {
>            z[i] += a_col[k] * x[j];
>            k += n;
>        }
>    }

This looks OK...

>
>/*
>** row echelon gaxpy
>*/
>    for (i = 0; i < m; i++) {  
>        z[i] = 0;
>        for (j = 0; j < n; j++) {
>            k = i * n + j;
>            z[i] += a_row[k] * x[j];
>        }
>    }
>}

Well small wonder row major looks slower! It isn't coded
like a C programmer would do it! :-) Why not

k=0;
for ( i=0; i<m; i++ ) {
   z[i]=0;
   for ( j=0; j<n; j++ ) {
      z[i]+=a_row[k]*x[j];
      k++;
   }
}

I'm sure the reason the BLAS used in M++ uses column major order is 
that it came from Fortran. There do not have to be any
appreciable speed differences resulting from either choice. Row major
order makes the code a little easier to understand from my perspective,
however.

Jeff



Newsgroups: comp.lang.c
From: jones@ils.nwu.edu
Subject: New Ph.D. Program
Organization: institute for the learning sciences
Date: Mon, 9 Nov 1992 20:02:17 GMT

T h e   L  E  A  R  N  I  N  G    S  C  I  E  N  C  E  S    P h. D.   P r o g r
a m


Preparing individuals for productive work and a   high quality of life in
today's society is a complex  challenge for schools and corporations. To meet
this challenge, Northwestern University has established a unique Ph.D. program
in the Learning Sciences. Its purpose is to advance the research and
development of innovative educational structures and technologies.

Research in the Learning Sciences is aimed at creating environments that offer
all students a rich variety of opportunities for learning to think effectively,
both within and outside of formal learning settings. Graduate student and
faculty research efforts are supported by a multimedia, networked computing 
infrastructure and an unusual commitment to developing technologies that
function effectively within their intended settings. 

The Learning Sciences is a synthesis of computational and social science
disciplines including artificial intelligence, cognitive and developmental
psychology, educational research, linguistics, computer science, anthropology
and fields that develop strategies for teaching complex subject matter. 

Through research, field work and apprenticeships, the Ph.D. program will
prepare its graduates to assume leadership roles in advancing the scientific
understanding and systematic practices of learning and teaching.

Students are eligible for competitively-awarded multi-year funding. To qualify
for financial aid, candidates should apply by January 15, 1992. Applications
received after that date may be  considered. Individuals with relevant teaching
experience or a strong academic  background in a field related to the Learning
Sciences are encouraged to apply. For  application materials or for further
information, contact:

Professor Roy Pea
Ph.D. Program Chair 
The Learning Sciences 
Northwestern University
1890 Maple Avenue
Evanston, IL  60201
phone: 708-491-8152
fax:    708-491-5258
email: jones@ils.nwu.edu
 
Newsgroups: comp.lang.c
From: msjle@uxa.ecn.bgu.edu (Joi L. Ellis)
Subject: Re: The Correct Way To Write C if-Statements
Organization: Educational Computing Network
Date: Thu, 5 Nov 1992 23:27:07 GMT

booloo@framsparc.ocf.llnl.gov (Mark Boolootian) writes:

[snip]

>[2] The original acronym was "CWAP" (for Code Written by Another Programmer).  
>    Unfortunately this acronym makes the speaker sound like Porky Pig, as in, 
>    "You Wascally Wabbit."  To avoid having world leading scientists at a large 
>    prestigious laboratory sound like Porky Pig, the acronym was changed to 
>    CRAP.
>-- 
>Mark Boolootian		booloo@llnl.gov		+1 510 423 1948

Elmer Fudd was the one with R problem, not Porky Pig...



Hysterically ROTFL yours,
-- 
Joi Ellis                      msjle@uxa.ecn.bgu.edu
Student Residential Programs   Western Illinois University
From: jos@and.nl (Jos Horsmeier)
Newsgroups: comp.lang.c
Subject: Re: To Recurse or NOT to recurse?
Date: 10 Nov 92 10:34:58 GMT
Organization: AND Software BV Rotterdam

In article <1992Nov10.003842.19169@asc386> mosmith@asc386 (Matt Smith) writes:
|The question is whether to recusively desend a linked-list or
|to do it iteraviely( a while loop).  My expeience has
|shown that the while loop is better in the long run.
|
|Reason:  Recursion uses the stack to store the recusive stuff (hope
|that's not too techy) which tends to blow up.  I prefer the other
|way

As a rule of thumb, I always use the following reasoning:

	`Never use recursion when the size of the stack is 
	linear proportional to the size of the problem.'

Traversing a linked list with n elements takes up to n slots on the
stack (and even a bit more for administration purposes) so I don't
use recursion here. 

Even when recursion is `needed', most of the time one of the recursive
branches can be eliminated, e.g finding an element in a sorted binary
tree can (intuitively) be written as:

tree_t *find(tree_t *t, data *d) {

	if (!t)					/* sentinel */
		return NULL;
	else if (t->d == d)			/* node found? */
		return t;
	else if (t->d > d)			/* search left */
		return find(t->left, d);
	else					/* search right */
		return find(tree->right, d);

}

The tail recursion can be eliminated by:

tree_t *find(tree_t *t, data *d) {

	for (; t; t= t->right) 			/* search right otherwise */

		if (t->d == d)			/* node found? */
			return t;
		else if (t->d > d)		/* search left */
			return find(t->left, d);

	return NULL;				/* sentinel */
}

Taking this example a bit further, the recursion can be totally
eliminated by the following transformation:

tree_t *find(tree_t *t, data *d) {

	while (t) 
		if (t->d == d)			/* node found */
			return t;
		else if (t->d > d)		/* search right */
			t= t->left;
		else				/* search left */
			t= t->right;

	return NULL;				/* sentinel */
}

I'm a bit of an `optimization freak' myself and I always try to eliminate
as much recursion as possible, because I still believe (and I know I'm
wrong most of the time) that function calls cause a teensy weensy bit
more overhead than simple iteration. But when the recursion violates
my rule of thumb, I don't even think about recursion any further.

kind regards,

Jos aka jos@and.nl
Newsgroups: comp.lang.c