semantic difference between [][] and **

P

Paul

Say I have:
char foo[][];
char** bar;

In my understanding, these two have the same meaning in memory.
Could someone elucidate upon these two types and their meanings?

Thanks,
Paul
 
V

Victor Bazarov

Paul said:
Say I have:
char foo[][];
char** bar;

In my understanding, these two have the same meaning in memory.

What is "meaning in memory"?
Could someone elucidate upon these two types and their meanings?

The former, IIUIC, is an error, since to declare a multidimensional array
you have to specify all sizes but the inner-most one.

V
 
D

Default User

Victor said:
Paul said:
Say I have:
char foo[][];
char** bar;

In my understanding, these two have the same meaning in memory.

What is "meaning in memory"?
Could someone elucidate upon these two types and their meanings?

The former, IIUIC, is an error, since to declare a multidimensional
array you have to specify all sizes but the inner-most one.


They way they are written, those are variable declarations, not
function parameters, so the first case would have to be initialized as
well.

char foo[][6] = {"one", "two", "three"};

Then the compiler can count the initializers and compute the missing
dimension.

Now, if used in a function declaration, then you can have:

void bar (char foo[][6]);

It's definitely not equivalent to:

void bar (char **foo);




Brian
 
M

marikallees

char foo[][]; is an invalid declaration. Only the first dimension size
can be omitted, and even then you're expected either to be using a
declaration without the definition, or initializing the array such that
the size can be calculated from the initializer.
these two have the same meaning in memory.
Not necessarily. Perhaps if you post some more code, and mention what
system and implementation you're using, a more thorough answer can be
given.

-Ren
 
R

Ren

char foo[][]; is an invalid declaration. Only the first dimension size
can be omitted, and even then you're expected either to be using a
declaration without the definition, or initializing the array such that
the size can be calculated from the initializer.
these two have the same meaning in memory.
Not necessarily. Perhaps if you post some more code, and mention what
system and implementation you're using, a more thorough answer can be
given.

-Ren
 
P

Paul

char foo[][]; is an invalid declaration. Only the first dimension size
can be omitted, and even then you're expected either to be using a
declaration without the definition, or initializing the array such that
the size can be calculated from the initializer.

these two have the same meaning in memory.

Not necessarily. Perhaps if you post some more code, and mention what
system and implementation you're using, a more thorough answer can be
given.

-Ren


Let's say:

char foo[16][16];
char **bar;

bar = new char*[16];
for(int i = 0; i < 16; i++)
{
bar = new char[16];
}


It is my understanding that foo and bar can be accessed and passed
around in similiar manner and maintain the same meaning.
I also think they can be cast from one to the next without error.

I have a suspicion I'm wrong, however. :)

-Paul
 
V

Victor Bazarov

Paul said:
char foo[][]; is an invalid declaration. Only the first dimension size
can be omitted, and even then you're expected either to be using a
declaration without the definition, or initializing the array such that
the size can be calculated from the initializer.

these two have the same meaning in memory.


Not necessarily. Perhaps if you post some more code, and mention what
system and implementation you're using, a more thorough answer can be
given.

-Ren


Let's say:

char foo[16][16];
char **bar;

bar = new char*[16];
for(int i = 0; i < 16; i++)
{
bar = new char[16];
}


It is my understanding that foo and bar can be accessed and passed
around in similiar manner and maintain the same meaning.


Similar, maybe. Same meaning, no. Same purpose, perhaps.
I also think they can be cast from one to the next without error.

That's incorrect.
I have a suspicion I'm wrong, however. :)

Yes, unfortunately, you are. 'foo' is an array of arrays, while 'bar'
is [a pointer to] an array of pointers. They have different types and
therefore behave differently in certain situations. Also, the derived
objects, *bar and *foo have different types, although now they are more
compatible than before, you may convert decltype(*foo) to decltype(*bar).
[Note: I use 'decltype' to convey the meaning, there is no such construct
in C++ yet].

The important difference (and that's where casting comes into play) is
that the memory layouts of what is designated by 'foo' and by 'bar' are
vastly different.

V
 
D

Default User

Paul said:
char foo[][]; is an invalid declaration. Only the first dimension
size can be omitted, and even then you're expected either to be
using a declaration without the definition, or initializing the
array such that the size can be calculated from the initializer.

these two have the same meaning in memory.

Not necessarily. Perhaps if you post some more code, and mention
what system and implementation you're using, a more thorough answer
can be given.

-Ren


Let's say:

char foo[16][16];
char **bar;

bar = new char*[16];
for(int i = 0; i < 16; i++)
{
bar = new char[16];
}


It is my understanding that foo and bar can be accessed and passed
around in similiar manner and maintain the same meaning.


Accessed, pretty much yes. Passed? Absolutely not.

http://www.eskimo.com/~scs/C-faq/q6.18.html
I also
think they can be cast from one to the next without error.

You can cast the array to the pointer and it won't cause an error
(because you did a cast). Doesn't mean it will work. The two constructs
will have different layouts in memory, and the pointer strides are
different. The name of array is converted to type pointer to array 16
of char.

Just disabuse yourself of this notion. Read ALL the FAQs on arrays and
pointers in the C FAQ (it's more useful for these questions).



Brian
 
J

Jonathan Mcdougall

Paul said:
Say I have:
char foo[][];
char** bar;

In my understanding, these two have the same meaning in memory.
Could someone elucidate upon these two types and their meanings?

The first one is an array of arrays of chars and second one is a pointer
to a pointer to a char. By the way, the definition of foo is illegal.

Both may be used the same way by, for example, allocating memory
dynamically and setting bar to have the same representation as foo. But
internally, in memory, they will not be the same. foo will be on the
stack and bar will be on the heap. foo will be continuous and bar will
probably be fragmented. foo will be an automatic object, bar will not
be. As I said, they may be used the same way, but logically, they would
represent different things as std::string::size() and
std::string::length() do the same thing, but have a different meaning.

Also, you could use them in a completly different way. For example, you
could use bar as a plain pointer to a pointer to a char :

void f(char **bar)
{
*bar = new char[10];
}

int main()
{
char *s = 0;

f(&s);

// s now points to a buffer of 10 chars

delete s;
}

Here, bar has the same type, but does not represent an array of arrays.
It all depends on what you do with them.


Jonathan
 
P

Paul

Alright.

Sorry for the error in the original post- I was just trying to do a
"generic code" kinda thing.

I appreciate the replies.

"The first one is an array of arrays of chars and second one is a
pointer to a pointer to a char."

Which makes sense, but it's rather confusing when moving from the 1-d case.

Thank you again.
-Paul
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top