[comp.lang.c] Funny behavior under TURBO compiler

anon@rouge.usl.edu (Anonymous NNTP Posting) (03/23/91)

Hi Netters,

I am unable to understand the behavior of following program compiled under TURBO C++ compiler. This program prints numbers 1-12. 

When "TB2 tbl" declaration is local to main() (as shown) the program works fine and the results are printed as :
1 2 3 4 5 6 7 8 9 10 11 12

If I make "TB2 tbl" a global variable the results are:
10 11 12 10 11 12 10 11 12 10 11 12

What's wrong , I couldn't figure out...

Anyone has clues..

Thanx,

Rajiv (EMAIL: rxd0219@usl.edu)
 


%%%%%%%%%%%%%%%%%%%%%%%%% CODE %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#include <stdio.h>
#include <alloc.h>

typedef int *TB1[3];
typedef TB1 *TB2[4];

main() 
{
	int i, j, k=1;
	TB2 tbl;

	for (i = 0; i < 4; i++)
		for (j = 0; j < 3; j++)
		{
		if ( ((*tbl[i])[j] = (int *)malloc(sizeof(int))) == NULL)
			{
			printf("malloc error\n");
			exit(1);
			}

		*((*tbl[i])[j]) = k++;
		}

	for (i = 0; i < 4; i++)
		for (j = 0; j < 3; j++)
			printf("%d ", *((*tbl[i])[j]));
}
%%%%%%%%%%%%%%%%%%%%% END OF CODE %%%%%%%%%%%%%%

		

torek@elf.ee.lbl.gov (Chris Torek) (03/23/91)

(One has to wonder if this was a joke, particularly coming from `anon'... )

In article <27668@rouge.usl.edu> anon@rouge.usl.edu (Anonymous NNTP Posting)
writes:
>#include <stdio.h>
>#include <alloc.h>

(alloc.h is not a standard C include file; the standard C include file
needed here is <stdlib.h>.  comp.lang.c is the wrong newsgroup for
discussing C++, but there is no `C++ only' code below, so the safest
thing is to just replace <alloc.h> with <stdlib.h> mentally and go on.)

>typedef int *TB1[3];
>typedef TB1 *TB2[4];

The type `TB2' is `array 4 of pointer to TB1'; the type TB1 is
`array 3 of pointer to int'; so the whole effect is to give anything
declared as a `TB2' the type

	array 4 of pointer to array 3 of pointer to int

or

	int *(*foo[4])[3];

Once such an object is declared, exactly four elements exist: foo[0]
through foo[3], each of which is a `pointer to array 3 of pointer to int'.

>main() 
>{
>	int i, j, k=1;
>	TB2 tbl;

At this point, tbl[0] through tbl[3] exist; none of these point anywhere.

>	for (i = 0; i < 4; i++)
>		for (j = 0; j < 3; j++)
>		{
>		if ( ((*tbl[i])[j] = (int *)malloc(sizeof(int))) == NULL)

In this expression, tbl[i] is an

	<object, pointer to array 3 of pointer to int, ?>

because tbl[i] has not been set to point anywhere.  Thus, *tbl[i] is an
error.  All bets are off.

Cure: set tbl[i] to point to one or more `array 3 of pointer to int'
objects before attempting to assign to (*tbl[i]).

Note that, once you have done this,

	tbl[i][0][j]

may be a clearer way to express `the i'th pointer, the 0'th array to
which it points, the j'th element to which that points'.  That element
is then a `pointer to int'.  If you make tbl[i] point to the first of
two `array 3 of pointer to int's, tbl[i][1][j] is also a valid object.
-- 
In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 415 486 5427)
Berkeley, CA		Domain:	torek@ee.lbl.gov