Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

2D array in C

Name: Anonymous 2012-02-01 8:30

If I have something like

char a[50][50];

Is something like this OK to do:

memset(a,0,2500);

In other words, does C make it into one array or is it actually an array of pointers?

Name: Anonymous 2012-02-01 8:31

C
If it ain't Lisp, it's crap.

Name: Anonymous 2012-02-01 8:39

you can access individual positions as a[x][y], the compiler will add the offset needed

Name: Anonymous 2012-02-01 8:53

So what you're asking is if the standard guarantees underlying contiguity? I don't know to be honest.

Name: Anonymous 2012-02-01 9:01

>>3
I know, but let's say I were to read/write from/to a file for example to save the array. Iterating through each position and storing them in another buffer and then writing that buffer into the file is an option, but what I'm asking if I really have to go through that.
After doing some tests it seems just fine, no matter how many dimensions in the array or if it's inside a struct. Still, I could just have been lucky up to this point and the buffers just happened to be stored right after each other, but ah well, I don't care as long as the code works. See no evil, hear no evil, speak no evil.

Name: Anonymous 2012-02-01 9:04

Yes. To be safe, though just use sizeof a instead of 2500.

Name: Anonymous 2012-02-01 9:05

>>4
Now that I think about it, it seems very unlikely considering that if you use the subscript operator on a multidimensional array object of dimension larger than 1 you will get a pointer to an array (in this case array char of size 50). So if you overstep that array you're invoking undefined behavior, the pointers are laid out contiguously, the arrays they point to are laid out contiguously, but I can't find any guarantee that they have to lie exactly after each other.

If you want to do this type of thing I would actually use malloc to first allocate pointers (in this case 50 char pointers) and then allocate a large block (in this case 2500 char elements) and set the pointers correctly in the array, that way you're guaranteed contiguous memory and you're not invoking any undefined behavior.

That being said I would be surprised to see any compiler that didn't lay them out contiguously and in order, but as I said I can't find any guarantees so beware ;-)

Name: Anonymous 2012-02-01 9:27

Yes, arrays are allocated as contiguous storage, C has no 2D arrays, but instead arrays of arrays, which are necessarily also contiguously allocated.

Name: Anonymous 2012-02-01 9:29

memset(a, 0, 2500); is undefined.

memset(a[0], 0, 2500); would be undefined as well.

Name: Anonymous 2012-02-01 9:46

>>9
memset(a, 0, 2500); is fine. you can cast a to (void*) if your compiler is a nazi but it shouldn't give errors.

Name: Anonymous 2012-02-01 9:48

check 'em

Name: Anonymous 2012-02-01 9:49

>>10
No it's not fine at all, a is an array of 50 pointers to array of chars, so you're overwriting the 50 pointers and then you're stepping out of bounds.

Name: Anonymous 2012-02-01 9:51

UNDEFINED BEHAVIOR

Name: Anonymous 2012-02-01 9:52

>>10
God damn are you mentally challenged or something?

Name: Anonymous 2012-02-01 9:52

>>12
if you defined it as a[50][50], it is allocated as 2500 element char array. a[i][j] is simply (a+i*50+j)

Name: Anonymous 2012-02-01 9:55

>>15
Damn you're dumb.

Name: Anonymous 2012-02-01 10:00

READ THE STANDARD OP

Name: Anonymous 2012-02-01 10:48

TWO WHOLE DIMENSIONS. INTERESTED?

Name: Anonymous 2012-02-01 10:50

>>2

If you ain't eaten peanuts, yer crackers.

Name: Anonymous 2012-02-01 11:11

>>9,14,16
Have you tried reading the standard or at least experimenting with a compiler before sprouting nonsense? I mean, you have not, but why?

If you tried experimenting first, then you'd have discovered that this code

#include <stdio.h>

char c[50][50] = {"abc"};

int main(void)
{
    printf("%p %p %p %p\n", &c, c, c[0], &c[0][0]);
    printf("%08x\n", *(unsigned int*)c);
    return 0;
}

prints the same value four times, then prints the hex representation of the "abc\0" (instead of some address). As do all other reasonable combinations of subscripting and addressing.

Also, only char * cptr = c[0]; works, attempting to initialize both char* and char** with c itself results in an "initialization from an incompatible pointer type" warning.

If you now read section 6.2.5 paragraph 20 and section 6.5.2.1 of the C99 standard, you'd discover than in C arrays are not pointers.

`char * ptr = "123"` means that somewhere an array of four chars is allocated, and additionally a pointer to char is allocated and initialized with the address of the array. `char arr[] = "123"` does not declare a pointer anywhere, there's no place in memory where the address of arr[0] is stored. `char[4]` is stored in the same way as `struct {char _1, _2, _3, _4}` (except I'm not sure that with the same padding).

In the same vein, an array of array of chars means that its items (arrays of char) are stored contiguously and in-place (just like chars in each array of char, or like structs in a struct of structs). Then section 6.5.2.1 describes how dereferencing works, please explicitly write how a[i][j] is interpreted and notice that there's only a single pointer dereferencing.

You apparently think that `char x[50][50]` is equivalent to `char * x[50]` with each element initialised with an address of some `char[50]` which can but are not required to be stored contiguously. This is false, there's no additional array of fifty pointers, only an array of 50 arrays of 50 chars.

Please make a habit of educating yourself before making an argument, this way you wouldn't make a fool of yourself and waste everyone's time.

Name: Anonymous 2012-02-01 11:34

Also padding, if I'm not mistaken, is applied at the end of the last array if you will, might vary on compiler but gcc should add padding bytes to the end only

Name: Anonymous 2012-02-01 11:35

check my doubles

Name: Anonymous 2012-02-01 12:24

>>[2][2]

INTERESTING!

Don't change these.
Name: Email:
Entire Thread Thread List