473,468 Members | 1,849 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

an array of pointers, causing segmentation fault

Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

return 0;
}

The output is:
a
b
c
Segmentation fault

Apr 26 '07 #1
27 6683
Jess wrote:
Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.
>
for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

return 0;
}

The output is:
a
b
c
Segmentation fault
"- Doctor, when I try changing the contents of the constant memory,
my program segfaults!
- Well, don't try changing the contents of the constant memory."

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '07 #2
On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:
Jess wrote:
>Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};

This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters. Then
you try to change them, and that's undefined behaviour.
Unfortunate indeed; however seeing as we're stuck with it I'm wondering
whether it's not too much to expect your compiler to pick up on it (with
at least a warning), since it will most likely complain if you try to
assign to any other const expression. Or would that contravene the
standard somewhere?

--
Lionel B
Apr 26 '07 #3
Lionel B schreef:
On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:
>Jess wrote:
>>Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters. Then
you try to change them, and that's undefined behaviour.

Unfortunate indeed; however seeing as we're stuck with it I'm wondering
whether it's not too much to expect your compiler to pick up on it (with
at least a warning), since it will most likely complain if you try to
assign to any other const expression. Or would that contravene the
standard somewhere?
Not sure if the following is correct:

int main()
{
char* x[] = {"a","b","c"};

foo(x[0]);
}

void foo(char *p)
{
*p = 'A';
}

My idea is that it may require a lot of tracking and tracing for a
compiler in order to detect all possible situations where the segfault
can occur.

Jeroen
Apr 26 '07 #4
Lionel B wrote:
On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:
>Jess wrote:
>>Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};

This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.

Unfortunate indeed; however seeing as we're stuck with it I'm
wondering whether it's not too much to expect your compiler to pick
up on it (with at least a warning), since it will most likely
complain if you try to assign to any other const expression. Or would
that contravene the standard somewhere?
No, a warning never contravenes the Standard. Indeed, many compilers
give plenty of warnings if you ask them. I am not sure, however, that
initialising a pointer to non-const char with the address of the first
element of an array of const char (string literal) is one of commonly
available warnings.

Perhaps PC-lint might help...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '07 #5
Jeroen wrote:
Lionel B schreef:
>On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:
>>Jess wrote:
Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.

Unfortunate indeed; however seeing as we're stuck with it I'm
wondering whether it's not too much to expect your compiler to pick
up on it (with at least a warning), since it will most likely complain if
you try to assign to any other const expression. Or
would that contravene the standard somewhere?

Not sure if the following is correct:

int main()
{
char* x[] = {"a","b","c"};

foo(x[0]);
}

void foo(char *p)
{
*p = 'A';
}

My idea is that it may require a lot of tracking and tracing for a
compiler in order to detect all possible situations where the segfault
can occur.
I don't think Lionel suggested tracking that. The mere initialisation
of 'x' with string literals should be the red flag. Once it's fixed,
then other problems can pop up and the whole thing will need to be
dealt with.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '07 #6
On Thu, 26 Apr 2007 09:20:19 -0400, Victor Bazarov wrote:
Jeroen wrote:
>Lionel B schreef:
>>On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:

Jess wrote:
Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!
>
#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>
>
using namespace std;
>
int main(){
char* x[] = {"a","b","c"};
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.

Unfortunate indeed; however seeing as we're stuck with it I'm
wondering whether it's not too much to expect your compiler to pick up
on it (with at least a warning), since it will most likely complain if
you try to assign to any other const expression. Or would that
contravene the standard somewhere?

Not sure if the following is correct:

int main()
{
char* x[] = {"a","b","c"};

foo(x[0]);
}

void foo(char *p)
{
*p = 'A';
}

My idea is that it may require a lot of tracking and tracing for a
compiler in order to detect all possible situations where the segfault
can occur.

I don't think Lionel suggested tracking that.
Hmm, I think I might have been, actually...
The mere initialisation
of 'x' with string literals should be the red flag. Once it's fixed,
then other problems can pop up and the whole thing will need to be dealt
with.
I presume by "fixing" it, you mean:

char* const x = "abc"; // compile error

const char* const x = "abc"; // ok

I suspect that might break a lot of legacy code, though. I was thinking
of:

char* const x = "abc"; // warning
...
*x = 'A'; // REALLY SCARY warning

The second warning could, I suppose, be an error (insofar as any code it
breaks was already badly broken...) but either way it might entail some
work on the compiler's part, as suggested by the previous poster.

--
Lionel B
Apr 26 '07 #7
On 04/26/2007 07:21 AM, Jess wrote:
Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

return 0;
}

The output is:
a
b
c
Segmentation fault
Constant strings in C++ are not generally writable; however, it's
perfectly acceptable to define arrays of characters that you can change:

char x[][2] = {"a", "b", "c"};

If you want to keep your old definition for "x", as a compiler
extension, gcc (g++) allows you to use the option "-fwritable-strings".
Other compilers may have a similar feature.

Apr 26 '07 #8
On Apr 26, 8:21 am, Jess <w...@hotmail.comwrote:
Hello, the following code failed with "segmentation fault". Could
someone tell me why it failed please? Thanks!

#include<iostream>
#include<string>
#include<cstring>
#include<cstddef>

using namespace std;

int main(){
char* x[] = {"a","b","c"};

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'
Correct, and "a" is a constant string literal which may be stored in
the read-only memory, modifying which causes undefined behavior.
>
for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

return 0;

}

The output is:
a
b
c
Segmentation fault
You are lucky to have a got a seg fault, UB may manifest itself in
many different ways e.g. getting your PC on fire.

/P
Apr 26 '07 #9

"Jess" <wd***@hotmail.comwrote in message
news:11**********************@n35g2000prd.googlegr oups.com...
>
*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;
I have my own follow-up question:

Is the above correct? Can you dereference an array member as if it were a
pointer? I would think the normal way to refer to the first character of
the first char array would be x[0][0], not *(x[0]). What he's doing is the
same as:

char xxx[10];
*xxx = 'a';

And that just doesn't seem right, to me. Is it?

-Howard
Apr 26 '07 #10
Howard wrote:
"Jess" <wd***@hotmail.comwrote in message
news:11**********************@n35g2000prd.googlegr oups.com...
>>
*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

I have my own follow-up question:

Is the above correct? Can you dereference an array member as if it
were a pointer?
In the original post members of 'x' array _are_ pointers.
I would think the normal way to refer to the first
character of the first char array would be x[0][0], not *(x[0]). What he's
doing is the same as:

char xxx[10];
*xxx = 'a';

And that just doesn't seem right, to me. Is it?
It is. 'xxx' (the name of the array), when used in an expression,
decays to a pointer to the first element. In fact, the indexing
expression (xxx[blah]) is not indexing at all, it's dereferencing:
*(xxx + blah) , and of course it's just the same thing with the
name decaying to a pointer.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 26 '07 #11

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:f0**********@news.datemas.de...
Howard wrote:
>"Jess" <wd***@hotmail.comwrote in message
news:11**********************@n35g2000prd.googleg roups.com...
>>>
*(x[0]) = 'A'; //since string "a" is an array of chars, and *(x[0])
is the location in memory that stores the first char in the array, ie
'a'. this line of code tries to change it to 'A'

for(size_t j = 0; j != 3; j++)
cout << *(x[j]) << endl;

I have my own follow-up question:

Is the above correct? Can you dereference an array member as if it
were a pointer?

In the original post members of 'x' array _are_ pointers.
> I would think the normal way to refer to the first
character of the first char array would be x[0][0], not *(x[0]). What
he's doing is the same as:

char xxx[10];
*xxx = 'a';

And that just doesn't seem right, to me. Is it?

It is. 'xxx' (the name of the array), when used in an expression,
decays to a pointer to the first element. In fact, the indexing
expression (xxx[blah]) is not indexing at all, it's dereferencing:
*(xxx + blah) , and of course it's just the same thing with the
name decaying to a pointer.
Ah, ok. Thanks, Victor.
-Howard

Apr 26 '07 #12
Victor Bazarov wrote:

No, a warning never contravenes the Standard. Indeed, many compilers
give plenty of warnings if you ask them. I am not sure, however, that
initialising a pointer to non-const char with the address of the first
element of an array of const char (string literal) is one of commonly
available warnings.
I glanced through the options for g++, but couldn't hit on one. There's
one to make them writable, which avoids the UB, but not a portable
solution.


Brian
Apr 26 '07 #13
Default User wrote:

I glanced through the options for g++, but couldn't hit on one.
There's one to make them writable, which avoids the UB, but not a
portable solution.
Eh, doesn't avoid the UB of course.


Brian
Apr 26 '07 #14
On Apr 27, 8:09 am, "Default User" <defaultuse...@yahoo.comwrote:
Victor Bazarov wrote:
No, a warning never contravenes the Standard. Indeed, many compilers
give plenty of warnings if you ask them. I am not sure, however, that
initialising a pointer to non-const char with the address of the first
element of an array of const char (string literal) is one of commonly
available warnings.

I glanced through the options for g++, but couldn't hit on one.
You must have overlooked -Wwrite-strings.

Apr 26 '07 #15
On Apr 26, 3:46 pm, Lionel B <m...@privacy.netwrote:
On Thu, 26 Apr 2007 09:20:19 -0400, Victor Bazarov wrote:
Jeroen wrote:
Lionel B schreef:
On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:
[...]
Not sure if the following is correct:
int main()
{
char* x[] = {"a","b","c"};
foo(x[0]);
}
void foo(char *p)
{
*p = 'A';
}
The code has undefined behavior.
My idea is that it may require a lot of tracking and tracing for a
compiler in order to detect all possible situations where the segfault
can occur.
I don't think Lionel suggested tracking that.
Hmm, I think I might have been, actually...
It's not reasonable. foo might be in another translation unit.
The mere initialisation
of 'x' with string literals should be the red flag. Once it's fixed,
then other problems can pop up and the whole thing will need to be dealt
with.
I presume by "fixing" it, you mean:
char* const x = "abc"; // compile error
const char* const x = "abc"; // ok
Not an error, but at least a warning.

In C++, the type of a string literal is char const[]. Which
converts implicitly to char const*. Normally, a string literal
could not be used to initialize as char*. To avoid breaking
legacy code, there is a special implicit conversion, however,
that only applies to char const* which are the direct result of
a string literal. When the committee made string literals char
const[], and introduced this conversion, it was their expressed
intent that compilers generate warnings when it was used. A
compiler *should* warn.
I suspect that might break a lot of legacy code, though. I was thinking
of:
char* const x = "abc"; // warning
...
*x = 'A'; // REALLY SCARY warning
The second warning could, I suppose, be an error (insofar as any code it
breaks was already badly broken...) but either way it might entail some
work on the compiler's part, as suggested by the previous poster.
The second could only be an error if the compiler can determine
that the code will actually be executed, for all possible input.
A warning on the first would be sufficient.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 27 '07 #16
On Apr 26, 8:21 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
It is. 'xxx' (the name of the array), when used in an expression,
decays to a pointer to the first element.
Not always, of course. But it's easier to remember the
exceptions (argument of sizeof, binding to a reference) than the
cases where the implicit conversion occurs. (Formally, it's
just another implicit conversion, which only occurs if
necessary. Practically, however, there are very few contexts in
an expression where an array type is legal. As Victor points
out, C++ doesn't support indexing into an array, as such.)
In fact, the indexing expression (xxx[blah]) is not indexing
at all, it's dereferencing: *(xxx + blah), and of course it's
just the same thing with the name decaying to a pointer.
Correct. And because it involves addition, it is commutative.
All that is required is that one of the operands be a pointer
(not an array!), and the other convertible into size_t. So
things like "abcd"[ i ], or even i[ "abcd" ] are legal.

(This isn't quite true. It only holds for pointers and
arithmetic types; if you overload operator+ and the unary
operator*, for example, you still can't use [], and you can
overload [] to have completely different semantics than *(a+b).
And while someone designing a smart pointer into an array class
should definitely try to respect the conventions, and make []
work exactly like *(a+b), he won't be able to make []
commutative, since it has to be a member.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 27 '07 #17
On Fri, 27 Apr 2007 01:44:45 -0700, James Kanze wrote:
On Apr 26, 3:46 pm, Lionel B <m...@privacy.netwrote:
>On Thu, 26 Apr 2007 09:20:19 -0400, Victor Bazarov wrote:
Jeroen wrote:
Lionel B schreef:
On Thu, 26 Apr 2007 08:44:29 -0400, Victor Bazarov wrote:

[...]
>Not sure if the following is correct:
>int main()
{
char* x[] = {"a","b","c"};
foo(x[0]);
}
>void foo(char *p)
{
*p = 'A';
}

The code has undefined behavior.
>My idea is that it may require a lot of tracking and tracing for a
compiler in order to detect all possible situations where the
segfault can occur.
I don't think Lionel suggested tracking that.
>Hmm, I think I might have been, actually...

It's not reasonable. foo might be in another translation unit.
The mere initialisation
of 'x' with string literals should be the red flag. Once it's fixed,
then other problems can pop up and the whole thing will need to be
dealt with.
>I presume by "fixing" it, you mean:
> char* const x = "abc"; // compile error
> const char* const x = "abc"; // ok

Not an error, but at least a warning.

In C++, the type of a string literal is char const[]. Which converts
implicitly to char const*. Normally, a string literal could not be used
to initialize as char*. To avoid breaking legacy code, there is a
special implicit conversion, however, that only applies to char const*
which are the direct result of a string literal. When the committee
made string literals char const[], and introduced this conversion, it
was their expressed intent that compilers generate warnings when it was
used. A compiler *should* warn.
Right, thanks for the clarification. I see now that gcc has a warning
flag -Wwrite-strings option which does exactly this, emitting a:

deprecated conversion from string constant to ‘char*’'

warning. The documentation states:

"When compiling C, give string constants the type const char[length] so
that copying the address of one into a non-const char * pointer will get
a warning; when compiling C++, warn about the deprecated conversion from
string constants to char *. These warnings will help you find at compile
time code that can try to write into a string constant, but only if you
have been very careful about using const in declarations and prototypes.
Otherwise, it will just be a nuisance; this is why we did not make -Wall
request these warnings."

.... and why I did not notice it.

[...]

--
Lionel B
Apr 27 '07 #18
On Apr 26, 10:44 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.
Is this because a string literal is always an array of const chars?
What if I have an array of string objects, rather than string
literals?

Apr 27 '07 #19
On Apr 26, 11:17 pm, Jeroen <no_m...@thanx.comwrote:
Not sure if the following is correct:

int main()
{
char* x[] = {"a","b","c"};

foo(x[0]);

}

void foo(char *p)
{
*p = 'A';

}
Does this code work?

Apr 27 '07 #20
On Apr 26, 11:46 pm, Lionel B <m...@privacy.netwrote:
char* const x = "abc"; // compile error

const char* const x = "abc"; // ok
If the first one raises compiler error, then why no error was raised
for my program above, which is

char* x[] = {"a","b","c"};
I would expect the compiler to raise an error because the code should
be:
const char* x[] = {"a","b","c"};

Apr 27 '07 #21
On Apr 27, 12:32 am, "Mumia W." <paduille.4061.mumia.w
+nos...@earthlink.netwrote:
Constant strings in C++ are not generally writable; however, it's
perfectly acceptable to define arrays of characters that you can change:

char x[][2] = {"a", "b", "c"};
"x" should be a 2D array, whose type is effectively char*, it looks to
me exactly the same as
char* x[] = {"a", "b", "c"};

If there's a multi-dimensional array "a" (say 2D), then "a"'s type can
always be regarded as some pointer type. for the example above, "a" is
a 2D array, and it's type is char*. Is this not right?

Apr 27 '07 #22
Jess schreef:
On Apr 26, 11:17 pm, Jeroen <no_m...@thanx.comwrote:
>Not sure if the following is correct:

int main()
{
char* x[] = {"a","b","c"};

foo(x[0]);

}

void foo(char *p)
{
*p = 'A';

}

Does this code work?
No, it should give the same segfault as the OP described. The code
snippet was only ment to illustrate that finding lines of code where a
segfault could occur can be difficult for a compiler (well, I just
thought it could be difficult...). It does not fit in the rest of the
discussion in this thread.

Jeroen
Apr 27 '07 #23
On Fri, 27 Apr 2007 03:26:23 -0700, Jess wrote:
On Apr 26, 11:46 pm, Lionel B <m...@privacy.netwrote:
> char* const x = "abc"; // compile error

const char* const x = "abc"; // ok
If the first one raises compiler error, then why no error was raised for
my program above, which is
Sorry, you took that out of context (which you've snipped); I didn't mean
it *does* raise an error, that was simply my interpretation of what
Victor Bazarov meant by "fixed" earlier in the thread, when he said "The
mere initialisation of 'x' with string literals should be the red flag.
Once it's fixed..."
^^^^^

[...]

--
Lionel B
Apr 27 '07 #24
On 04/27/2007 05:33 AM, Jess wrote:
On Apr 27, 12:32 am, "Mumia W." <paduille.4061.mumia.w
+nos...@earthlink.netwrote:
>Constant strings in C++ are not generally writable; however, it's
perfectly acceptable to define arrays of characters that you can change:

char x[][2] = {"a", "b", "c"};

"x" should be a 2D array, whose type is effectively char*, it looks to
me exactly the same as
char* x[] = {"a", "b", "c"};
No, the first element of 'x' has two characters.
If there's a multi-dimensional array "a" (say 2D), then "a"'s type can
always be regarded as some pointer type. for the example above, "a" is
a 2D array, and it's type is char*. Is this not right?
No, if you pass it to a function, it's more likely to be treated as
"(char*)[2]"--a pointer to two characters.

The two constructs are fundamentally different.

This
char * x[] = {"a", "b", "c"};
creates three pointers that point to the various strings.

This
char * x[][2] = {"a", "b", "c"};
is the same as saying this,
char * x[3][2] = {"a", "b", "c"};
, and it creates no pointers. The data to create the strings is laid out
in memory, and the compiler remembers where each of the strings begin.
Apr 27 '07 #25
Mumia W. wrote:
[..]
The two constructs are fundamentally different.

This
char * x[] = {"a", "b", "c"};
creates three pointers that point to the various strings.

This
char * x[][2] = {"a", "b", "c"};
is the same as saying this,
char * x[3][2] = {"a", "b", "c"};
, and it creates no pointers.
If I may correct this a bit...

First of all both declarations should be without the asterisk:

char x[][2] =
char x[3][2] =

Second of all, the latter declaration (for the sake of clarity) we
should probably write as

char x[3][2] = { { 'a', '\0' }, { 'b', '\0' }, { 'c', '\0' } };
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 27 '07 #26
On Apr 27, 12:21 pm, Jess <w...@hotmail.comwrote:
On Apr 26, 10:44 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
This is an unfortunate language feature [that ought to be abolished
years ago!!!] which led you to believe you are allowed to change the
values of the characters to which elements of 'x' point. You have
initialised 'x' with addresses of arrays of _constant_ characters.
Then you try to change them, and that's undefined behaviour.
Is this because a string literal is always an array of const chars?
Yes.
What if I have an array of string objects, rather than string
literals?
Then it's an array of string objects. The standard certainly
allows things like:
std::string array[] = { "abc", "nothing", "etc." } ;
In this case, it's an array of string objects, and the literals
only serve to initialize the objects, and are not accessible
otherwise.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 27 '07 #27
Old Wolf wrote:
On Apr 27, 8:09 am, "Default User" <defaultuse...@yahoo.comwrote:
Victor Bazarov wrote:
No, a warning never contravenes the Standard. Indeed, many
compilers give plenty of warnings if you ask them. I am not
sure, however, that initialising a pointer to non-const char with
the address of the first element of an array of const char
(string literal) is one of commonly available warnings.
I glanced through the options for g++, but couldn't hit on one.

You must have overlooked -Wwrite-strings.
Ah. There you go.


Brian
Apr 27 '07 #28

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: pandapower | last post by:
Hi, I know about the equivalence of pointer and arrays.But my doubt comes when its for multidimentional arrays.I have read the C faq but still have some doubts. Suppose I have a declaration as...
6
by: damian birchler | last post by:
If I run the following I get a segmentation fault: #define NAMELEN 15 #define NPERS 10 typedef struct pers { char name; int money; } pers_t;
19
by: Sameer | last post by:
Hi friends, I am using Mandriva Linux 9.2 and gcc. My source code is, int chunkin ; //no error int i ; for (i=0;i<7225;i++) { chunkin = somedata ;
8
by: Ben | last post by:
Hi, I am having trouble debugging a segmentation fault...here's my data structure: typedef struct CELL *pCELL; /* Pointers to cells */ struct CELL { SYMBOL symbol; pCELL prev_in_block;...
8
by: SP | last post by:
The following code crashes after I add the two nested FOR loops at the end, I am starting to learn about pointers and would like to understand what I'm doing wrong. I think the problem is the way...
27
by: lovecreatesbea... | last post by:
This code snippet is an exercise on allocating two dimension array dynamically. Though this one is trivial, is it a correct one? Furthermore, when I tried to make these changes to the original...
13
by: ElderGeek | last post by:
Hello. I'm pretty new to C, and having a problem which I suspect this has to do with how I'm handling (or not handling) pointers. I have an array of dirent structures which I am passing to a...
26
by: sumsin | last post by:
Can you please explain the below pointer initializations: char *cptr = "test"; /* gives no error and warnings */ int *iptr = 10; /* gives only warning */ float *fptr = 3.14; /* gives error */ ...
3
by: Anna | last post by:
Could you please help me? I got a segmentation fault message while trying to assign a pointer = pointer like this: bufferlist=(buffer_t*)buffernew; What's the error by doing this? Here is the...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.