Array of pointers + memory Location

S

Slain

I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.
My colleague argues that in flat bed memory this should not be done. A
new should be used to allocate the memory and then point to it. Of
course he didnt do the best job explaining, hence my question to you
guys, if you can shed some more light on this.

Thanks in anticipation
 
N

Nick Keighley

I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.
yes

My colleague argues that in flat bed memory

in *what*?
this should not be done.

why not?
A
new should be used to allocate the memory and then point to it.

why? Why waste the cost of a new (and they are quite expensive)
when it isn't necessary?

Of
course he didnt do the best job explaining, hence my question to you
guys, if you can shed some more light on this.

I've little sympathy with people who give apparently motiveless
technical advice. If he knows the reason why doesn't he tell you?
 
V

Victor Bazarov

Nick said:
I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.

yes

Except that it shouldn't compile since "John" is an array of const
char and 'str[1]' is a pointer to non-const char. There is no
conversion without a cast. The intent probably was to declare 'str'
as 'char const* str[10];'

V
 
S

Slain

Nick said:
I have more of a conceptual question now. Let us say I do this:-
char *str[10]; --> create an array of pointers
str[1]= "John";
I thought this would automatically put John at some memory space and
point str[1] to it.

Except that it shouldn't compile since "John" is an array of const
char and 'str[1]' is a pointer to non-const char. There is no
conversion without a cast. The intent probably was to declare 'str'
as 'char const* str[10];'

V

It does compile as long as it is inside main or any function. So may
be it does a type conversion.
 
S

Slain

Nick said:
I have more of a conceptual question now. Let us say I do this:-
char *str[10]; --> create an array of pointers
str[1]= "John";
I thought this would automatically put John at some memory space and
point str[1] to it.

Except that it shouldn't compile since "John" is an array of const
char and 'str[1]' is a pointer to non-const char. There is no
conversion without a cast. The intent probably was to declare 'str'
as 'char const* str[10];'

V

It does compile as long as it is inside main or any function. So may
be it does a type conversion.
 
J

Jeff Schwab

Victor said:
Nick said:
I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.
yes

Agreed, "John" now lives in static storage.
Except that it shouldn't compile since "John" is an array of const
char and 'str[1]' is a pointer to non-const char. There is no
conversion without a cast.

There is such a conversion, although it is deprecated. From
[conv.array]: "This conversion is considered only when there is an
explicit appropriate pointer target type, and not when there is a
general need to convert from an lvalue to an rvalue."
The intent probably was to declare 'str'
as 'char const* str[10];'

I believe any attempt to modify the string is undefined behavior, so (as
you suggest) the OP is surely better off with char const*. Even better,
IMO, would be replacing the raw array of raw pointers with a vector (or
tr1 array) of std::string.
 
M

Micah Cowan

Victor Bazarov said:
Nick said:
I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.

yes

Except that it shouldn't compile since "John" is an array of const
char and 'str[1]' is a pointer to non-const char. There is no
conversion without a cast. The intent probably was to declare 'str'
as 'char const* str[10];'

No cast is required, for compatibility with C (it's a, deprecated,
standard conversion, and only applies to string literals).

No diagnostic is required, but decent implementations will issue one
anyway.
 
J

James Kanze

Nick said:
I have more of a conceptual question now. Let us say I do
this:-
char *str[10]; --> create an array of pointers
str[1]= "John";
I thought this would automatically put John at some memory
space and point str[1] to it.
yes
Except that it shouldn't compile since "John" is an array of
const char and 'str[1]' is a pointer to non-const char. There
is no conversion without a cast.

Yes there is, for historical reasons. A string literal (but no
other char const[] or char const*) will convert implicitly to a
char*, if (and only if) "there is an explicit appropriate ponter
target type, and not when there is a general need to convert
from an lvalue to an rvalue". (I think that means that the
literal is being used to assign to or initialize a pointer---and
probably that static_cast< char* > is legal as well.)

This conversion is deprecated, so I would expect a good compiler
to warn.
The intent probably was to declare 'str' as 'char const*
str[10];'

That's definitely what it should be if you expect to initialize
it with string literals.

For the original poster: "An ordinary string literal has type
`array of n const char' and static storage duration[...]"
(§2.13.4/1 of the standard), and "A string literal is an
lvalue;[...]" (§5.1/1). In other words, the compiler will
arrange for the necessary memory to be there, initialized and
present for the entire duration of the program. There is
absolutely no reason to use dynamic allocation in this case.
 
U

utab

I have more of a conceptual question now. Let us say I do this:-

char *str[10]; --> create an array of pointers
str[1]= "John";

I thought this would automatically put John at some memory space and
point str[1] to it.
My colleague argues that in flat bed memory this should not be done. A
new should be used to allocate the memory and then point to it. Of
course he didnt do the best job explaining, hence my question to you
guys, if you can shed some more light on this.

Thanks in anticipation

After I have read this thread, I created a small test program and
played with that a little bit, And I have some minor questions on it,
using strings is always welcome though.

Here is the code
#include <iostream>
#include <string>

int main()
{

char *str[2];

str[0]="55555";
str[1]="22";

char * p1=0,p2=0; // **
p1 = &(str[0][0]); // **
p2 = &(str[1][0]); // **

std::cout << "Size of char:" << std::endl;
std::cout << sizeof(char) << "byte(s)" << std::endl;

std::cout << p1 << std::endl;
std::cout << p2 << std::endl;

std::cout << '\"' << str[0] << '\"' << " is of " <<
strlen(str[0])*sizeof(char) << " bytes" << std::endl;
std::cout << '\"' << str[1] << '\"' << " is of " <<
strlen(str[1])*sizeof(char) << " bytes" << std::endl;

for(int i=0;i!=strlen(str[0]);++i)
std::cout << &(str[0+i*sizeof(char)]) << std::endl;
return 0;

}

and compiler(g++) gives an error

ptr.cc: In function 'int main()':
ptr.cc:14: error: invalid conversion from 'char*' to 'char'

however I am a bit confused with this, since I thought that I can take
the address of an lvalue, I used p1 = &(str[0][0]);

+ is not str[0][0] a char and lvalue to which I can assign?
+ should not using the address_of operator on it return an address of
a character which may be assigned to a "char *"?

The second question is that commenting the starred lines in the code
in the new version of the code

#include <iostream>
#include <string>

int main()
{
char *str[2];
str[0]="55555";
str[1]="22";

//char * p1=0,p2=0;
//p1 = &(str[0][0]);
//p2 = &(str[1][0]);

std::cout << "Size of char:" << std::endl;
std::cout << sizeof(char) << "byte(s)" << std::endl;

std::cout << &str[0][0] << std::endl;
std::cout << &str[1][0] << std::endl;

std::cout << '\"' << str[0] << '\"' << " is of "
<<strlen(str[0])*sizeof(char) << " bytes" << std::endl;
std::cout << '\"' << str[1] << '\"' <<" is of "<<
strlen(str[1])*sizeof(char) << " bytes" <<std::endl;

for(int i=0;i!=strlen(str[0]);++i)
std::cout << &(str[0+i*sizeof(char)]) << std::endl;
return 0;

}

and output is:
Size of char:
1byte(s)
55555 ###
22 ###
"55555" is of 5 bytes
"22" is of 2 bytes
0xbfd60d1c
0xbfd60d20
0xbfd60d24
0xbfd60d28
0xbfd60d2c

And the last question is that I have an array of pointers to char, how
can I get the start address of each char array that are pointed by the
pointers in the array? This is a bit related to my 1st question where
I thought I can get it with &(str[0][0]), but apparently there is sth
I am missing.

Best,
 
U

utab

I have more of a conceptual question now. Let us say I do this:-
char *str[10]; --> create an array of pointers
str[1]= "John";
I thought this would automatically put John at some memory space and
point str[1] to it.
My colleague argues that in flat bed memory this should not be done. A
new should be used to allocate the memory and then point to it. Of
course he didnt do the best job explaining, hence my question to you
guys, if you can shed some more light on this.
Thanks in anticipation

After I have read this thread, I created a small test program and
played with that a little bit, And I have some minor questions on it,
using strings is always welcome though.

Here is the code
#include <iostream>
#include <string>

int main()
{

char *str[2];

str[0]="55555";
str[1]="22";

char * p1=0,p2=0; // **
p1 = &(str[0][0]); // **
p2 = &(str[1][0]); // **

std::cout << "Size of char:" << std::endl;
std::cout << sizeof(char) << "byte(s)" << std::endl;

std::cout << p1 << std::endl;
std::cout << p2 << std::endl;

std::cout << '\"' << str[0] << '\"' << " is of " <<
strlen(str[0])*sizeof(char) << " bytes" << std::endl;
std::cout << '\"' << str[1] << '\"' << " is of " <<
strlen(str[1])*sizeof(char) << " bytes" << std::endl;

for(int i=0;i!=strlen(str[0]);++i)
std::cout << &(str[0+i*sizeof(char)]) << std::endl;
return 0;

}

and compiler(g++) gives an error

ptr.cc: In function 'int main()':
ptr.cc:14: error: invalid conversion from 'char*' to 'char'

however I am a bit confused with this, since I thought that I can take
the address of an lvalue, I used p1 = &(str[0][0]);

+ is not str[0][0] a char and lvalue to which I can assign?
+ should not using the address_of operator on it return an address of
a character which may be assigned to a "char *"?

The second question is that commenting the starred lines in the code
in the new version of the code

#include <iostream>
#include <string>

int main()
{
char *str[2];
str[0]="55555";
str[1]="22";

//char * p1=0,p2=0;
//p1 = &(str[0][0]);
//p2 = &(str[1][0]);

std::cout << "Size of char:" << std::endl;
std::cout << sizeof(char) << "byte(s)" << std::endl;

std::cout << &str[0][0] << std::endl;
std::cout << &str[1][0] << std::endl;

std::cout << '\"' << str[0] << '\"' << " is of "
<<strlen(str[0])*sizeof(char) << " bytes" << std::endl;
std::cout << '\"' << str[1] << '\"' <<" is of "<<
strlen(str[1])*sizeof(char) << " bytes" <<std::endl;

for(int i=0;i!=strlen(str[0]);++i)
std::cout << &(str[0+i*sizeof(char)]) << std::endl;
return 0;

}

and output is:
Size of char:
1byte(s)
55555 ###
22 ###
"55555" is of 5 bytes
"22" is of 2 bytes
0xbfd60d1c
0xbfd60d20
0xbfd60d24
0xbfd60d28
0xbfd60d2c

And the last question is that I have an array of pointers to char, how
can I get the start address of each char array that are pointed by the
pointers in the array? This is a bit related to my 1st question where
I thought I can get it with &(str[0][0]), but apparently there is sth
I am missing.

Best,

Sorry, that I forgot to ask my second question : the output I get as
shown with ###, why do I get this output? They are all related a bit.
 
T

Triple-DES

[snip]
And the last question is that I have an array of pointers to char, how
can I get the start address of each char array that are pointed by the
pointers in the array? This is a bit related to my 1st question where
I thought I can get it with &(str[0][0]), but apparently there is sth
I am missing.

If you have an array of pointers to char, then the start address of
each char array is the pointer itself (at least unformally). So
&(str[0][0]) == str[0]

DP
 

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,776
Messages
2,569,603
Members
45,196
Latest member
ScottChare

Latest Threads

Top