# 2D Dynamically allocated pointer arrays

Show 80 post(s) from this thread on one page
Page 1 of 3 123 Last
• 06-08-2005
Lionmane
2D Dynamically allocated pointer arrays
Hi!

I'm trying to create (insert subject)!

I get an error "missing ';' before type" on the line where I declare my pointer. Can anyone tell me what I'm doing wrong?

Code:

``` #include<stdio.h> //#include<stdlib.h> /* This program demonstrates recursive functions and dynamic, multi-dimensional pointer arrays. It will calculate the total factorial value for multiple groups of items. You enter the total number of items, and the number of groups you will have.  Then you enter the number of items in each group.  The program error-checks to make sure the number of items entered in each groups adds up to be the total number of items. */ //        Prototypes. unsigned long factr (unsigned long n); void main () { //        These are in order of appearance.         unsigned long num_items = 0;         unsigned long num_groups = 0;         unsigned long loop = 0;         unsigned long total = 0;         unsigned long quantity = 0;         unsigned long numerator = 0;         unsigned long denominator = 1;         printf ("\n\nHow many items total?\n");         scanf ("%u", &num_items);         printf ("\n\nHow many groups?\n");         scanf ("%u", &num_groups);         if (num_groups > num_items)         {                 printf("\n\nError! Can't have more groups than items!\n\n");                 exit (1);         } //        Array dimensioning.         unsigned long *group_total[num_groups][2];         group_total = malloc (num_groups*2*sizeof(int));         if(!group_total)         {                 puts ("\n\nERROR! Not enough Memory!\n\n");                 exit (1);         } //        Array initialization.         for (loop = 1; loop <= num_items; loop++)         {                 group_total[loop][1] = 0;                 group_total[loop][2] = 0;         }         loop = 0; //        Array data-entry.         for (loop = 1; loop <= num_groups; loop++)         {                 printf ("\n\nHow many in group %d\n", loop);                 scanf ("%u", &quantity);                 group_total[loop][1] = quantity;                 total = total + quantity;         }         loop = 0; //        Error checking and factorial calculations for each group         if (total = num_groups);         {                 for (loop = 1; loop <= num_groups; loop++)                 {                         group_total[loop][2] = factr (quantity);                 }                 loop = 0;         }         else         {                 printf ("\n\nTotal number of items not equal to total items entered!\n\n");                 free (group_total);                 exit (1);         }         total = 0; //        Final calculations.         numerator = factr (num_items);         for (loop = 1; loop <= num_groups; loop++)         {                 denominator = denominator * group_total[loop][2];         }         total = numerator / denominator;         printf ("\n\nTotal factorial for this mess: %u\n\n", total);         total = 0;         loop = 0;         free (group_total); } //        Factorial engine. unsigned long factr (unsigned long n) {         unsigned long answer;         if (n==1) return (1);         answer = n==0 ? 1: n * factr (n - 1); // recursive call         return (answer); }```
• 06-08-2005
Dave_Sinkula
In C90, declare variables before any statements.
• 06-08-2005
Lionmane
I thought that was the problem... :-(

Can I make my pointer declaration a function by itself and retain the pointer after the function returns?

mw
• 06-08-2005
Dave_Sinkula
>Can I make my pointer declaration a function by itself and retain the pointer after the function returns?

I don't think I fully understand, but sure.

There are plenty of issues with your code that are handled in the FAQ.
Code:

`for (loop = 1; loop <= num_items; loop++)`
Arrays are indexed from 0 to N-1, not 1 to N.
• 06-08-2005
Lionmane
What I meant was:

The program asks the user how many groups there are and then declares a pointer array of that size. I can do this by calling a function that declares a pointer, but then when the function returns the pointer is gone.

Since I'm already using a recursive function, I want to close all of the extra functions before I start "recursing". I guess I can call a function that sets up my pointer and then calls the recursive function to perform my calculations, but is this going to "flood my stack" or whatever?

I know about the starting index of an array being zero but aren't pointers indexed starting at one?

mw
• 06-08-2005
Dave_Sinkula
Quote:

Originally Posted by Lionmane
What I meant was:

The program asks the user how many groups there are and then declares a pointer array of that size. I can do this by calling a function that declares a pointer, but then when the function returns the pointer is gone.

Perhaps pass a pointer to pointer. Also,
http://www.eskimo.com/~scs/C-faq/q6.16.html

Quote:

Originally Posted by Lionmane
I know about the starting index of an array being zero but aren't pointers indexed starting at one?

No. Pointers point.
• 06-09-2005
Lionmane
Ok, I've changed my code:

Code:

``` #include<stdio.h> #include<stdlib.h> /* This program demonstrates recursive functions and dynamic, multi-dimensional pointer arrays. It will calculate the total factorial value for multiple groups of items. You enter the total number of items, and the number of groups you will have.  Then you enter the number of items in each group.  The program error-checks to make sure the number of items entered in each groups adds up to be the total number of items. */ //        Prototypes. unsigned long factr (unsigned long num_items2, unsigned long num_groups2); unsigned long factorial_engine (unsigned long n); void main () {         unsigned long num_items = 0;         unsigned long num_groups = 0;         printf ("\n\nHow many items total?\n");         scanf ("%u", &num_items);         printf ("\n\nHow many groups?\n");         scanf ("%u", &num_groups);         if (num_groups > num_items)         {                 printf("\n\nError! Can't have more groups than items!\n\n");                 exit (1);         }         else         {                 factr (num_items, num_groups);         } } unsigned long factr (unsigned long num_items2, unsigned long num_groups2) { //        These are in order of appearance.         unsigned long loop = 0;         unsigned long total = 0;         unsigned long quantity = 0;         unsigned long numerator = 0;         unsigned long denominator = 1; //        Array dimensioning.         unsigned long *group_total;         group_total = malloc (num_groups2*2*sizeof(int));         if(!group_total)         {                 puts ("\n\nERROR! Not enough Memory!\n\n");                 exit (1);         } //        Array initialization.         for (loop = 1; loop <= num_items2; loop++)         {                 group_total[loop][1] = 0;                 group_total[loop][2] = 0;         }         loop = 0; //        Array data-entry.         for (loop = 1; loop <= num_groups2; loop++)         {                 printf ("\n\nHow many in group %d\n", loop);                 scanf ("%u", &quantity);                 group_total[loop][1] = quantity;                 total = total + quantity;         }         loop = 0; //        Error checking and factorial calculations for each group         if (total = num_groups2);         {                 for (loop = 1; loop <= num_groups2; loop++)                 {                         group_total[loop][2] = factr (quantity);                 }                 loop = 0;         }         else         {                 printf ("\n\nTotal number of items not equal to total items entered!\n\n");                 free (group_total);                 exit (1);         }         total = 0; //        Final calculations.         numerator = factr (num_items2);         for (loop = 1; loop <= num_groups2; loop++)         {                 denominator = denominator * group_total[loop][2];         }         total = numerator / denominator;         printf ("\n\nTotal factorial for this mess: %u\n\n", total);         total = 0;         loop = 0;         free (group_total); } //        Factorial engine. unsigned long factorial_engine (unsigned long n) {         unsigned long answer;         if (n==1) return (1);         answer = n==0 ? 1: n * factr (n - 1); // recursive call         return (answer); }```
But now when I tried to reference a subscript in group_total it gives me "subscript requires array or pointer type". I think it's telling me I didn't declare my pointer as a 2D array.

I looked up that link you gave me about multi-dimensional arrays, but I don't understand it.

mw
• 06-09-2005
swoopy

Quote:

Arrays are indexed from 0 to N-1, not 1 to N.
You forgot to change your code for this.

>void main ()
main return an int:
Code:

`int main(void)`
> if (total = num_groups2);
This statement contains two errors:
1) = means assignment not equality.
2) The semicolon at the end means everything following the if() gets executed regardless of the outcome of the condition.

> group_total[loop][1] = 0;
> group_total[loop][2] = 0;
If you're not using the second element, then just make this one dimension.
Code:

`                group_total[loop] = 0;`
• 06-09-2005
Salem
> unsigned long *group_total;
> group_total = malloc (num_groups2*2*sizeof(int));
If you're trying to malloc the equivalent of unsigned long group_total[num_groups2][2];
This is what you do

Code:

```  unsigned long (*group_total)[2];   group_total = malloc ( num_groups2 * sizeof *group_total );```
Be very careful here, (*group_total)[2] is NOT the same thing as *group_total[2], so don't go leaving out the () for the fun of it, it simply won't work.

By the way, this only works if your minor dimensions are constant. If they vary, then you need to start with unsigned long **group_total

Then you need to fix all your loops to index from 0 to N-1
Code:

```for ( i = 0 ; i < num_groups2 ; i++ ) {   for ( j = 0 ; j < 2 ; j++ ) {     group_total[i][j] = 0;   } }```
When you're done, it's simply
Code:

`  free( group_total );`
• 06-09-2005
Lionmane
Thanks guys! I'm still not understanding pointers very well it seems... :-(

The "C for Dummies" has little to no info about pointers. I have "The Complete Reference: C" by Herbert Schildt but I couldn't figure it out with that either.

Anyway, I was finally able to compile without any errors but now I'm getting a pop-up window that says "Debug Error!" and gives me some obscure message. The program runs fine until it begins calculating the factorials.

The error is "Damage: after Normal block (#44) at 0x00431DF0." Any ideas there? Sorry to ask so many questions. I'm trying to learn C pretty much on my own.

mw
• 06-09-2005
earth_angel
If the size of the array varies, you have to dynamically allocate the rows and columns:

Code:

``` //allocate 1D array of pointers, one pointer per row         a = (int **) calloc(row, sizeof(int *)); //allocate one column element array of ints for each row         for (i=0; i<row; ++i)         {                 a[i]=(int *) calloc(column, sizeof(int)); //fill the matrix                 for (i=0; i< row; ++i)                 {                         for (j=0; j<column; ++j)                                 a[i][j] = 2;                 }         }```
calloc fills the array with 0's automatically. You can have the user specify what the number of rows and columns is.

See if that helps.
• 06-09-2005
quzah
Don't cast malloc and calloc in C. (Or any other function that returns a void * for that matter.)

Quzah.
• 06-09-2005
Lionmane
Quzah, how do you create 2D dynamic arrays (first subscript is dynamic, second is static)? I thought malloc was used to check the memory.

mw
• 06-10-2005
quzah
I never said to not use malloc. I said don't typecast it's return.
Code:

```char **twodee; int numofrows = 5, numofcols = 10, x; twodee = malloc( sizeof( char * ) * numofrows ); for( x = 0; x < numofrows; x++ )     twodee[ x ] = malloc( sizeof( char ) * numofcols );```
The 'sizeof( char )' is just to illustrate the point, were this any other type than characters. The reason being, 'sizeof( char )' always evaluates to one, so it's not needed in this example. Were this any other type, it would be needed there (of the appropriate type (int, float, struct foo, etc etc).

Quzah.
• 06-10-2005
Salem
> The error is "Damage: after Normal block (#44) at 0x00431DF0." Any ideas there?
Yeah, you modified some memory which wasn't yours.
Typically, you walked off the end of whatever array you allocated.

Post some more code.

> The Complete Reference: C" by Herbert Schildt
Oh dear - hope you still have the receipt, and time to take it back.
http://www.plethora.net/~seebs/c/c_tcr.html
A book so famed in infamy, it's got it's own buzzword
http://catb.org/~esr/jargon/html/B/bullschildt.html
Show 80 post(s) from this thread on one page
Page 1 of 3 123 Last