1

The code below is me trying to instantiate a 2d array, and it instantiating incorrectly: THE CODE:

    FILE* kernalFile = fopen(argv[1], "r");
    int rKernalSize;
    fscanf(kernalFile, "%d", &rKernalSize);
    unsigned int rKernal[rKernalSize][rKernalSize];

Data froma break point right after that code is ran: rKernalSize VALUES:

Name : rKernalSize
    Details:3
    Default:3
    Decimal:3
    Hex:0x3
    Binary:11
    Octal:03

rKernal VALUES:

Name : rKernal
    Details:0x7ffffffe0cd0
    Default:[0]
    Decimal:[0]
    Hex:[0]
    Binary:[0]
    Octal:[0]

or

rKernal[][0]

It should be rKernal[3][3] and here is the file so you can look at it. If wanted:

3 -1 1 0 1 0 -1 0 -1 1 3 -1 1 0 1 0 -1 0 -1 1 3 -1 1 0 1 0 -1 0 -1 1

TLDR: rKernalSize is correct (3) but when I create the 2d Array with rKernal[rKernalSize][rKernalSize] it does not instantiate correctly! It instatiates as rKernal[][0] maybe thats default but should be rKernal[3][3]

2
  • What does "it does not instantiate correctly" mean? Commented Oct 27, 2010 at 2:50
  • What do you mean by saying "does not instantiate correctly!"? Commented Oct 27, 2010 at 2:50

2 Answers 2

2

Forget what the debugger is telling you. In your code, immediately following:

unsigned int rKernal[rKernalSize][rKernalSize];

put the statement:

printf ("%d\n", sizeof(rKernal) / sizeof(unsigned int));

and see what it prints out (hopefully 9).

It's possible the debugging information, created at compile time, is not enough to properly determine the sizes of variable length arrays.


By way of example, even though gcc supports variable length arrays, gdb itself couldn't properly handle them as recently as late 2009 and there's still no mention of them in the documentation dated October 2010.

So I suspect that is the problem, especially since the test code I provided above output 9 as expected.

Sign up to request clarification or add additional context in comments.

5 Comments

isn't sizeof evaluated at compile time? (ed: I guess for dynamically sized arrays in C99 it's evaluated at run time...)
If I do that I get this warning: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int
@Mark: No. C99 6.5.3.4/2 states If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
@Jacob: And when you run it, what happens?
There you go then (ignore the warning, this line is a temporary one for debugging: you could fix it with a proper format string but YAGNI). Bottom line: your array is being created correctly. The fact that your debugger does not have enough information to figure out how big it is at runtime is a deficiency of the debugger.
1

The basic problem here is that rKernalSize isn't known at compile time when that array is being allocated. At compile time, the value of int rKernalSize is compiler-dependent (unless the new C standard explicitly makes it 0; 0's the value I'd bet on anyway.) So when the code is loaded, there's a symbol rKernal that represents the address of a secrtion of memory containing no bytes.

But then you run the program, and read '3' with your scanf; when you dumpt the results, you see '3'.

This code, by the way, wouldn't work in straight C -- you must allocate before the first executable statement. This will compile in C++.

Now, if you want, using straight C, to do something like this, here's what you need:

  • Read your size as you have using scanf.

  • Allocate the memory for your array using malloc, which will look something like

x

int ** ary;
int rkSize;  // what you scanf'd into
if((ary = malloc(rkSize*rkSize*sizeof(unsigned int)))==NULL){
     // for some reason your malloc failed.  You can't do much
     fprintf(stderr,"Oops!\n");
     exit(1);
 }
 // If you got here, then you have your array
  • Now, because of the pointer-array duality in C, you can treat this as your array x

    ary[1][1] = 42; // The answer

5 Comments

Exactly, you'll have to use "malloc" and allocate your memory dynamically. c-faq.com/aryptr/dynmuldimary.html
@Michael: Actually, no you don't. C99 introduced the concept of variable length arrays so this code is valid under that iteration of the standard. Buried in that linked page is the snippet Finally, in C99 you can use a variable-length array. :-)
GCC does it just fine. The standards been around since, well, '99 I guess so, if your vendor doesn't support it *cough*Microsoft*cough*, you should think about moving :-) And the fact that the question wasn't about a compile time error means that the questioner's compiler also supports C99.
I don't believe you can index into ary as ary[1][1] as you've indicated; when you're allocating only one block of memory there's not enough information for the compiler to turn that into an appropriate offset. Indexing would instead need to be of the form ary[1*rkSize + 1]
@paxdiablo: Correct you are. I've done almost all my C coding to the C90 standard I think. Anyway, thanks!

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.