Thread: Array within Array Doubt.

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    16

    Array within Array Doubt.

    Hello,
    I want to create pre-formatted data within a constant struct within other struct, but I get the weird "braces around scalar initializer" from the compiler (Cygwin/warning).
    The code is the following
    Code:
    struct {
    			char name[60];
    			int req;
    } tachs;
    const struct {
    	char name[60];
    	struct tachs* tach[3];
    } achv[] = {
    	{ "What", {//error is displayed here...
    			{ "Name1", 1000000 },//error is displayed here...
    			{ "Name2", 100000000 },//error is displayed here...
    			{ "Name3", 1000000000 },//error is displayed here...
    		}//error is displayed here...
    	},
    	{ "Something", {//error is displayed here...
    			{ "Name1", 1 },//error is displayed here...
    			{ "Name2", 5 },//error is displayed here...
    			{ "Name3", 10 },//error is displayed here...
    		}
    	},//etc (there were more below in the same way as the ones above.
    };
    Its php equivalent would be:
    PHP Code:
    $arr = array( "Name", array( array("Name2","1"), array("Name2","2"), array("Name3","3") ), ...etc ); 
    I would like to know what I'm doing wrong, tried to google for the error but I didn't find any enlightenment.
    Thank you for your time.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    You can't create anonymous data that you can just point at, except when the pointer is char* and the thing being pointed to is a "string".

    It takes 2 steps
    Code:
    struct tachs data[] = {
    			{ "Name1", 1000000 },
    			{ "Name2", 100000000 },
    			{ "Name3", 1000000000 },
    			{ "Name1", 1 },
    			{ "Name2", 5 },
    			{ "Name3", 10 },
    };
    const struct {
    	char name[60];
    	struct tachs* tach[3];
    } achv[] = {
    	{ "What", { &data[0], &data[1], &data[2] } },
    	// and so on
    };
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    If you are using C99, you could use compound literal.



    Code:
    const struct {
    	char name[60];
    	struct tachs* tach[3];
    } achv[] = {
        { "What",  &(struct tachs) { "Name1", 1000 } , &(struct tachs) { "Name2",100000}, ... },
     
    
    };

  4. #4
    Registered User
    Join Date
    Nov 2010
    Posts
    16
    Thanks to both of you,
    I've used Bayint Naung's solution.
    However I'm now getting 'error: request for member 'req' in something not a structure or union'
    when trying to write on 'achv->tach[0].req', when writing to achv->tach[0]->req there is no error upon compiling but when the program runs it crashes at that line (identified with gdb, SIGSEGV).
    Writing on achv->name is performed smoothly, however.
    Any clues on what I could be doing wrong?
    Thank you for your time.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    That's because, when using Baying Naung's solution, you put the values in a portion of read only memory. This is similar to the writable strings issue, and why the following would fail:
    Code:
    char *p = "Some string literal";
    strcpy(p, "foo");
    However I'm now getting 'error: request for member 'req' in something not a structure or union'
    when trying to write on 'achv->tach[0].req'
    That's because you have an array of pointers: struct tachs *tach[3], not an array of tachs objects, like so: struct tachs tach[3].

    when writing to achv->tach[0]->req there is no error upon compiling but when the program runs it crashes at that line (identified with gdb, SIGSEGV)
    Declaring your array as struct tachs *tach[3] means it is an array containing 3 pointers to struct tachs objects. The initialization is only concerned with setting the pointer values to point to a valid struct tachs object. The pointer itself, i.e. the address of the tachs object tach[0] is pointing to, can be changed since that is in writable memory. It says nothing about where the struct tachs objects you define are put. It is putting them in a read-only section of memory. The compiler is then placing the information for the tachs objects in read-only memory. You can modify achv->tach[0], but not achv->tach[0]->req.

    You would be better off using something like:
    Code:
    const struct {
    	char name[60];
    	struct tachs tach[3];      // No asterisk. This is an array of objects, not pointers
    } achv[] = {

  6. #6
    Registered User
    Join Date
    Nov 2010
    Posts
    16
    Thank you, removing the asterisk did it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 16
    Last Post: 05-29-2009, 07:25 PM
  2. from 2D array to 1D array
    By cfdprogrammer in forum C Programming
    Replies: 17
    Last Post: 03-24-2009, 10:33 AM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  5. Array Program
    By emmx in forum C Programming
    Replies: 3
    Last Post: 08-31-2003, 12:44 AM