C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 08-04-2009, 04:00 AM   #1
Registered User
 
Join Date: Mar 2009
Posts: 109
dynamic array in STRUCT

Hi everyone,

I am new to structs but I need them for some complex problem where the struct not simply contains arrays or pointers, but also arrays of pointers as shown below.

What I can't figure out is how to dynamically allocate the array of pointers defined in the struct.

Can anyone help me with this issue?
thank you in advance. I can write my code without structs, but I rather use them to make it more readable and efficient.

Thank you in advance

Code:
#define PROB_ENTRIES 10
#define MAX_INPUT_ENTRIES 40

typedef struct
{

	char *problem[];
	float PROBVars[MAX_INPUT_ENTRIES]
	
} input;



main()
{
...

char *problem[PROB_ENTRIES];
	for(i=0; i<PROB_ENTRIES; i++)
		problem[i] = (char*) malloc(32 * sizeof(char *));
		
...
}
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 04:13 AM   #2
Registered User
 
GL.Sam's Avatar
 
Join Date: Aug 2009
Posts: 39
Quote:
float PROBVars[MAX_INPUT_ENTRIES]
Add a semicolon.

Quote:
problem[i] = (char*) malloc(32 * sizeof(char *));
Remove an asterisk.

Better now?

btw, don't use structs for such a simple case. I don't even understand why are you declaring *problem[] over again.
__________________
The only good is knowledge and the only evil is ignorance.
~Socrates

Last edited by GL.Sam; 08-04-2009 at 04:19 AM.
GL.Sam is offline   Reply With Quote
Old 08-04-2009, 04:26 AM   #3
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by GL.Sam View Post
Add a semicolon.


Remove an asterisk.

Better now?

btw, don't use structs for such a simple case. I don't even understand why are you declaring *problem[] over again.
Hi Sam, thanks for replying. I sent just a simple psuedo-code as example but I think I didn't explain myself correctly.

The struct that I want to use is actually going to contain many elements (arrays of loats, arrays of pointers, strings, constants, etc.), but most of the arrays and arrays of pointers that I want to use inside the struct are supposed to be dynamic.

What I cannot do correctly is dynamically allocate them and I don't know whether that step must be done inside the struct or in the main.c

Thank you again
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 04:54 AM   #4
Registered User
 
GL.Sam's Avatar
 
Join Date: Aug 2009
Posts: 39
Don't ever try to allocate anything being in a struct block. And if you use array notation [] in there, it shouldn't be empty. It goes smt like following:

Code:
#include <stdio.h>
#include <string.h>

#define PROB_ENTRIES 10


struct input
{

	char *problem[PROB_ENTRIES];
	
};


int main(void)
{
        struct input huh;
	int i;

	for (i = 0; i < PROB_ENTRIES; i++)
	{
		huh.problem[i] = (char*) malloc(32 * sizeof(char));
        	strcpy(huh.problem[i], "What?");
		printf("%s\n", huh.problem[i]);
	}
	
        return 0;

}
__________________
The only good is knowledge and the only evil is ignorance.
~Socrates
GL.Sam is offline   Reply With Quote
Old 08-04-2009, 05:14 AM   #5
Registered User
 
Join Date: Mar 2009
Posts: 109
Hi Sam, thank youi very much! This helps a lot

All the best,
cfd
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 05:22 AM   #6
Registered User
 
GL.Sam's Avatar
 
Join Date: Aug 2009
Posts: 39
No problem. Uh, and don't forget about the free()! I myself did.
__________________
The only good is knowledge and the only evil is ignorance.
~Socrates
GL.Sam is offline   Reply With Quote
Old 08-04-2009, 05:37 AM   #7
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by GL.Sam View Post
No problem. Uh, and don't forget about the free()! I myself did.
sure; about details I'll take care of them. I'm new to structs but still proficient in C

thank you again
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 05:55 AM   #8
Woof, woof!
 
zacs7's Avatar
 
Join Date: Mar 2007
Location: Australia
Posts: 3,139
Just 2 tips:
* Drop the sizeof(char) since it's always 1.
* Drop the cast on malloc()
__________________
"I.T. gets the chicky-babes" - M. Kelly
bakefile | vim
zacs7 is offline   Reply With Quote
Old 08-04-2009, 06:09 AM   #9
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by zacs7 View Post
Just 2 tips:
* Drop the sizeof(char) since it's always 1.
* Drop the cast on malloc()
Hi Zacs, thanks for the hints

Best,
cfd
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 06:22 AM   #10
and the hat of vanishing
 
Salem's Avatar
 
Join Date: Aug 2001
Location: The edge of the known universe
Posts: 21,214
> Drop the sizeof(char) since it's always 1.
Writing
p = malloc ( sizeof(*p) * numRequired );
will save you from doing something like

int *p = malloc( 10 );
in the belief that you've allocated 10 int's.

Better still, because the sizeof uses the pointer variable itself for working out the size, you don't have to look back to make sure that the declaration type, and the type in the sizeof agree with one another. Change one, and the other is instantly correct!

Choose one idiom, that always works.

Optional programming, like
- leaving braces off single-statements inside a control (for, if etc)
- sizeof(char) being 1 for malloc
- optional ( ) in complex arithmetic or boolean expressions
will, sooner or later, mutate from"simple" code into something not so simple, and the optional becomes necessary. It might be months before the bug is noticed, and weeks more before it's finally tracked down and fixed.
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
Up to 8Mb PlusNet broadband from only £5.99 a month!
Salem is offline   Reply With Quote
Old 08-04-2009, 06:24 AM   #11
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by Salem View Post
> Drop the sizeof(char) since it's always 1.
Writing
p = malloc ( sizeof(*p) * numRequired );
will save you from doing something like

int *p = malloc( 10 );
in the belief that you've allocated 10 int's.

Better still, because the sizeof uses the pointer variable itself for working out the size, you don't have to look back to make sure that the declaration type, and the type in the sizeof agree with one another. Change one, and the other is instantly correct!

Choose one idiom, that always works.

Optional programming, like
- leaving braces off single-statements inside a control (for, if etc)
- sizeof(char) being 1 for malloc
- optional ( ) in complex arithmetic or boolean expressions
will, sooner or later, mutate from"simple" code into something not so simple, and the optional becomes necessary. It might be months before the bug is noticed, and weeks more before it's finally tracked down and fixed.
Hi Salem,

great hints; thanks so much

Best regards,
cfd
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 07:43 AM   #12
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by GL.Sam View Post
Don't ever try to allocate anything being in a struct block. And if you use array notation [] in there, it shouldn't be empty. It goes smt like following:

Code:
#include <stdio.h>
#include <string.h>

#define PROB_ENTRIES 10


struct input
{

	char *problem[PROB_ENTRIES];
	
};


int main(void)
{
        struct input huh;
	int i;

	for (i = 0; i < PROB_ENTRIES; i++)
	{
		huh.problem[i] = (char*) malloc(32 * sizeof(char));
        	strcpy(huh.problem[i], "What?");
		printf("%s\n", huh.problem[i]);
	}
	
        return 0;

}
Hi again Sam,

I wrote a *.h file that contains my struct, and the definition of the function that uses the struct elements, and the corresponding READ_INPUT.c file and main calling READ_INPUT()

1) READ_INPUT.h:
Code:
//Struct for the Boundary condition codes and values:
typedef struct struct_bc
{
    unsigned int nbdy_nodes;	// Number of boundary nodes
    unsigned int *NODE;			// Node index number
    unsigned int *BDY_CODE;		// Array of the boundary codes
    float *BDY_VALUES;			// Array of boundary values: size [nbdy_nodes]x[nvariables]

}bc ;	//bc as Boundary Conditions	

void READ_BC(char *bdy_file, bc *BDYCS);
2) READ_INPUT.c:
Code:
void READ_BC(char *bdy_file, bc *BDYCS)
{
	FILE *bdyf_ID;
	char header[16];
	
	BDYCS.NODE = (unsigned int*) malloc(10 * sizeof(unsigned int *));

	free(BDYCS.NODE);
	
return;
}
but I get the following error in compilation:

Code:
READ_INPUT.c: In function ‘READ_BC’:
READ_INPUT.c:127: error: request for member ‘NODE’ in something not a structure or union
READ_INPUT.c:151: error: request for member ‘NODE’ in something not a structure or union
make: *** [main.o] Error 1
what am I doing wrong in using the structure arrays to allocate?

thanks a lot
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 09:13 AM   #13
Registered User
 
slingerland3g's Avatar
 
Join Date: Jan 2008
Location: Seattle
Posts: 476
Use:

Code:
   BDYCS->NODE = (unsigned int*) malloc(10 * sizeof(unsigned int *));
slingerland3g is offline   Reply With Quote
Old 08-04-2009, 09:26 AM   #14
Registered User
 
Join Date: Mar 2009
Posts: 109
Quote:
Originally Posted by slingerland3g View Post
Use:

Code:
   BDYCS->NODE = (unsigned int*) malloc(10 * sizeof(unsigned int *));
Thank you
cfdprogrammer is offline   Reply With Quote
Old 08-04-2009, 09:37 AM   #15
C++ Witch
 
laserlight's Avatar
 
Join Date: Oct 2003
Location: Singapore
Posts: 10,352
I suggest that you reserve the use of fully capitalised names to macro names. Use descriptive names instead of using comments. Together, and excluding the inclusion guards, I would suggest this for your header file:
Code:
typedef struct boundary_conditions
{
    unsigned int num_nodes; // Number of boundary nodes
    unsigned int *node;     // Node index number
    unsigned int *code;     // Array of the boundary codes
    float *values;          // Array of boundary values: size [nbdy_nodes]x[nvariables]
} boundary_conditions;

void read_boundary_conditions(char *bdy_file, boundary_conditions *bdy_conds);
Now, what slingerland3g suggested is correct. However, an even better version (using my suggested changes) would be:
Code:
bdy_conds->node = malloc(10 * sizeof(*bdy_conds->node));
The reason is that if the type of the node member changes, this would be factored in automatically, instead of having to change from unsigned int* to the new type.
__________________
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar

Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
laserlight is offline   Reply With Quote
Reply

Tags
array, dynamic, pointer, struct

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
array of struct pointers simo_mon C Programming 4 05-11-2009 08:34 PM
populate an array struct flipguy_ph C Programming 10 04-17-2009 04:07 PM
Assignment HELP!! cprogrammer22 C Programming 35 01-24-2009 02:24 PM
Struct with a ptr to a dynamically allocated array of other structures :( michael- C Programming 10 05-18-2006 11:23 PM
Request for comments Prelude A Brief History of Cprogramming.com 15 01-02-2004 10:33 AM


All times are GMT -6. The time now is 09:05 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22