-3

My goal is to access max_resources_per_client[1][1].

In conf.c that can't be modified, I got:

#define NUM_CLIENTS 5
#define NUM_RESOURCES 3
const unsigned int num_clients = NUM_CLIENTS;
const unsigned int num_resources = NUM_RESOURCES;
const unsigned int max_resources_per_client[NUM_CLIENTS][NUM_RESOURCES] = {
  {7, 5, 3},
  {3, 2, 2},
  {9, 1, 2},
  {2, 2, 2},
  {4, 3, 3},
};

In my file main.c I have:

extern const unsigned int num_clients;
extern const unsigned int num_resources;
extern const unsigned int **max_resources_per_client;

How can I access max_resources_per_client[1][1] without causing a segmentation fault?


Note: Trying to do

extern const unsigned int max_resources_per_client[num_clients][num_resources];

results in an error: variably modified ‘max_resources_per_client’ at file scope


Note: Trying to do extern const unsigned int max_resources_per_client[NUM_CLIENTS][NUM_RESOURCES];

results in error: NUM_RESOURCES’ undeclared here (not in a function)

RainingChain
  • 7,397
  • 10
  • 36
  • 68

2 Answers2

2

Refer to this -> How to declare extern 2d-array in header?

You need, at a minimum, to include the right-most column size for a 2-D array. You can declare it like this:

extern unsigned char LCD[][64];

Otherwise the compiler would not be able to compute the offset after the first row.

Community
  • 1
  • 1
lamirap
  • 510
  • 1
  • 3
  • 8
1

max_resources_per_client is a two-dimensional array of unsigned ints, which is different than unsigned int ** (pointer to pointer to unsigned int). The extern declaration needs to declare max_resources_per_client as an array. The extern declaration should look like the definition in conf.c but without the initializer:

const unsigned int max_resources_per_client[NUM_CLIENTS][NUM_RESOURCES];

You actually don't need NUM_CLIENTS in order for the compiler to know what's going on, so you could declare it like this:

const unsigned int max_resources_per_client[][NUM_RESOURCES];

The compiler at least needs to know the second dimension so it can calculate the correct offset into the array. The above declaration tells it that each "row" of the array contains NUM_RESOURCES unsigned ints, which allows it to calculate the offset of any element.

Andy Schweig
  • 6,597
  • 2
  • 16
  • 22
  • How can I access NUM_RESOURCES defined in `config.c` from file `main.c`? Note: There is no `config.h`. – RainingChain Mar 20 '16 at 04:14
  • Ideally, `NUM_RESOURCES`would be in a .h file (along with the extern declarations). You can't use that array without knowing that dimension. Do you have any flexibility in rearranging this code? – Andy Schweig Mar 20 '16 at 04:17
  • 1
    The code in your "update" only works if the array definintion is also changed to `const unsigned int max_resources_per_client[NUM_RESOURCES * NUM_CLIENTS];` . With the original definition it is undefined behaviour. – M.M Mar 20 '16 at 04:48
  • It's a total hack and I don't recommend using it, but of course it works. The two-dimensional array as declared is 15 consecutive unsigned ints. We know exactly how it's laid out in memory, so having the compiler treat it as a one-dimensional array and doing the indexing manually will produce the correct result. In what situation would that not work? (I debated posting that solution because it's not clean, but it does work. Would it have been better to not post it?) – Andy Schweig Mar 20 '16 at 05:03
  • @AndySchweig One of the outcomes of undefined behavior is seemingly correct execution. I suggest you remove the invalid example. – 2501 Mar 20 '16 at 07:27
  • Agreed. I removed it. Thanks for the feedback. – Andy Schweig Mar 20 '16 at 08:23