2

Why the content is not printed well (e.g. Segmentation Fault/NULL)? I'm passing the entire nested struct (i.e. the array list lp) to the main list. Any suggestion? I spent two days to understand what I wrong without success. I would to have an explanation about it.

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

struct list
{
    char *a;
    char *b;
} lp[10];

typedef struct
{
    int k;
    struct list thelist[2];
} palist;

int main()
{

    lp[0].a     = "One";
    lp[0].b     = "Two";

    lp[1].a     = "Three";
    lp[1].b     = "Four";

    palist final_list = {10, *lp};

    printf("%s, %s", final_list.thelist[1].a, final_list.thelist[1].b);

    return 0;
}
4
  • 1
    lp is an array of structs, why are you using *lp, try using just lp Commented Jun 14, 2020 at 8:09
  • 1
    in palist, thelist is an array. You attempt to initialize with *lp which is simply the first struct list in lp. That won't work. Commented Jun 14, 2020 at 8:10
  • @kiner_shah, @David C. Rankin I removed the pointer palist final_list = {10, lp}; but the content is printed as (null), (null). Commented Jun 14, 2020 at 8:13
  • 1
    Change palist final_list = {10, *lp}; to palist final_list = {10, { lp[0], lp[1] } }; Commented Jun 14, 2020 at 8:28

2 Answers 2

6

What you have to understand is that on access, an array is converted to a pointer to the first element (subject to 4-exceptions not relevant here) C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)

When you attempt to initialize thelist with *lp you are attempting to initialize an array of struct list from the first element in lp. Assuming you change the intialization from {10, *lp} to (10, lp) that still will not work because now lp is a pointer to the first element which you attempt to use to initialize an array.

In order to accommodate the array/pointer conversion, you need to declare thelist as a pointer not an array, e.g.

typedef struct
{
    int k;
    struct list *thelist;
} palist;

(You can initialize a pointer with a pointer and all will be well)

Now using the initializer {10, lp} will provide a pointer for the initialization of thelist and your assignment will work (but you must keep track of the number of elements that are valid -- final_list[2].... would invoke Undefined Behavior as the elements 2 and beyond are not initialized)

Your total code would be:

#include <stdio.h>

struct list
{
    char *a;
    char *b;
} lp[10];

typedef struct
{
    int k;
    struct list *thelist;
} palist;

int main(void) {

    lp[0].a     = "One";
    lp[0].b     = "Two";

    lp[1].a     = "Three";
    lp[1].b     = "Four";

    palist final_list = {10, lp};

    printf("%s, %s\n", final_list.thelist[1].a, final_list.thelist[1].b);

    return 0;
}
Sign up to request clarification or add additional context in comments.

4 Comments

That's curious! I wonder why the 4th exception of the operand of the _Alignof operator isn't stated in C18 (n2310) anymore. I've always cite quotes without the statement of the _Alignof operator as exception.
That is curious. I'll have to read up on that and reduce the number of exceptions :)
I wanted to start asking about that but I just found stackoverflow.com/questions/51803814/…
@RobertSsupportsMonicaCellio -- thank you. I'm glad Eric asked the question and I"m glad ex answered -- I would not have sussed out the fine points of the type name / expression argument being the reason that _Alignof disappeared from the paragraph. Correction "(subject to 3-exceptions not relevant here... if using the C18 standard)" ... :)
-1

There are many other ways to initialize or assign this list in the form with the array

typedef struct
{
    int k;
    struct list thelist[2];
} palist;

for example

    palist final_list = {10, {lp[0], lp[1]}};
    final_list = (palist){10, {lp[0], lp[1]}};
    final_list = (palist){10,};
    memcpy(final_list.thelist, lp, sizeof(final_list.thelist));

https://godbolt.org/z/fUjLtE

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.