strange problem

J

junw2000

The following code can be compiled. But When I run it, it causes
"Segmentation fault".

#include <iostream>

int main(){
char **c1;

*c1 = "HOW"; // LINE1

std::cout <<"1"<<std::endl;

++(*c1);
*c1 = "ARE";

std::cout <<"2"<<std::endl;
++(*c1);
*c1 = "YOU";
std::cout <<"3"<<std::endl;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;

}

Why LINE1 causes "Segmentation fault"?

What is the correct way to write the above code?

Thanks a lot.
 
A

Alf P. Steinbach

* (e-mail address removed):
The following code can be compiled. But When I run it, it causes
"Segmentation fault".

#include <iostream>

int main(){
char **c1;

*c1 = "HOW"; // LINE1

std::cout <<"1"<<std::endl;

++(*c1);
*c1 = "ARE";

std::cout <<"2"<<std::endl;
++(*c1);
*c1 = "YOU";
std::cout <<"3"<<std::endl;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;

}

Why LINE1 causes "Segmentation fault"?

Dereferencing an uninitialized pointer - Undefined Behavior.

What is the correct way to write the above code?

Rather, what's a better way to use your compiler? Up the warning
levels. Ensure that you get a clean compile (no warnings), always.

To output the text "HOW ARE YOU", do

std::cout << "HOW ARE YOU" << std::endl;

Just avoid pointers, they're dangerous.
 
L

Luke Meyers

The following code can be compiled. But When I run it, it causes
"Segmentation fault".

Yes. The english name for that is "invalid memory access."
#include <iostream>

int main(){
char **c1;

This is a variable which holds a memory address. If it held a valid
address (it doesn't, unless by chance), the contents of the memory at
said address would be another memory address. If *that* address were
valid, it would be the location of a variable of type char.

A little confusing? Yes. Easy to mix up and make a mistake, resulting
in a seg fault? Yup.
*c1 = "HOW"; // LINE1

Right, so here you're dereferencing a pointer which does not hold a
valid memory address. Hence, seg fault. If *c1 held a valid pointer
(to a variable of type char*), the result of this operation would be to
make *c1 point to the area in static memory containing the string
literal "HOW."
What is the correct way to write the above code?

Use std::string. It exists to prevent you from feeling the pain you
now feel.

Luke
 
J

junw2000

Thanks.
Certainly, std::string is safer. I am trying to learn
pointer-to-pointer to char.
If using C language, how to initialize c1 to three strings---"HOW",
"ARE", "YOU"?

Thanks again.
 
P

Phlip

junw2000 said:
Certainly, std::string is safer.

This newsgroup always instructs students to start with the Standard library
stuff.
I am trying to learn
pointer-to-pointer to char.
If using C language, how to initialize c1 to three strings---"HOW",
"ARE", "YOU"?

Start with three pointers to characters:

char const * strings[] = { "HOW", "ARE", "YOU" };

And point to the first one:

char const * * p = strings;

Now p[1] points to "ARE", and p[1][1] points to 'R'.

You might be able to Google for "aggregate initializers" from here.
 
L

Luke Meyers

Certainly, std::string is safer. I am trying to learn
pointer-to-pointer to char.

Sure. The best way, in my opinion, to learn to use char** correctly is
to first learn about using, for example, int**. Integers are easier to
deal with because you don't have the added complications of string
literals, string lengths, null termination, etc. It may sound like I'm
being perversely intransigent, but the fact is that the fundamental
things you're failing to understand, in the code you posted, are issues
which pertain to all pointer-to-pointer types. The reason you're
failing to understand them has a lot to do with the fact that you're
trying to jump straight into the complexities of char** without
understanding those fundamentals.
If using C language, how to initialize c1 to three strings---"HOW",
"ARE", "YOU"?

This isn't a C newsgroup. If you want help with C, try comp.lang.c
(actually, I see that you already did so).

Luke
 
P

Phlip

Luke said:
This isn't a C newsgroup. If you want help with C, try comp.lang.c
(actually, I see that you already did so).

Mr. Manners reminds the Gentle Poster that some neophytes have not yet
learned to write, "if using C-style C++..."

Note the transition was from std::string; the poster was trying to
distinguish from the C++ Standard Library.
 
L

LuB

The following code can be compiled. But When I run it, it causes
"Segmentation fault".

#include <iostream>

int main(){

char* d1 = "";
char** c1 = &d1;
*c1 = "HOW"; // LINE1

std::cout <<"1"<<std::endl;

++(*c1);
*c1 = "ARE";

std::cout <<"2"<<std::endl;
++(*c1);
*c1 = "YOU";
std::cout <<"3"<<std::endl;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;
(*c1)++;
std::cout <<*c1<<std::endl;

}


As the previous posters implied, this approach is not recommended.

-LuB
 
T

Thomas J. Gritzan

LuB said:
char* d1 = "";
char** c1 = &d1;

Are you sure you want to do this?

Advances the pointer after d1.

Will do bad things.

Even worser.
As the previous posters implied, this approach is not recommended.

And does not work. You should better use std::string and std::vector.

Thomas
 
J

Jim Langston

The following code can be compiled. But When I run it, it causes
"Segmentation fault".

#include <iostream>

int main(){
char **c1;

Okay, c1 is a pointer to a pointer of char.
*c1 = "HOW"; // LINE1

Here you are saying to change the contents of where c1 points to point to
the string literal "HOW". But, c1 is not yet pointing to valid memory.
It's pointing anywhere since it was never initialized. So you are
attempting to change memory that your program doesn't "own", hence the
segmentation fault.

What it looks like you are trying here is to have c1 to be an array of
pointers to char. So you need to set aside the memory for the pointers.

This would work:

char* c1[3];
c1[0] = "HOW";

because now c1 is an array of 3 pointers to char, and the memory has been
allocated for 3 pointers. Also, though, you could now reference these by
your char** such as;

char* c0[3];
char** c1 = c0;
*c0 = "HOW";

because c1 now points to memory that has been allocated (by the declaration
of c0 which allocated the space for 3 pointers).
 
L

LuB

Thomas said:
Are you sure you want to do this?

No I'm not sure. What do you think?
Advances the pointer after d1

I'm sure you are correct - but I can't tell .. but I've no idea what
your point is. *c1 is now "OW"
Will do bad things.

Again - I'm sure you are correct ... but what are you talking about?

g++ isn't complaining.
Even worser.

Again - I can't disagree ... cause I've no idea what you are talking
about.

Someone else posted this ... I added two lines at the top ... the
program compiles and appears to run in g++. I'm having trouble parsing
your post. Again, I'm sure your are correct - but I've no idea what you
are saying?
And does not work. You should better use std::string and std::vector.

Ok ... I'm not saying your wrong.

But I beg to take issue with your verbage.

It does indeed work.

$ g++ -v
Using built-in specs.
Target: i386-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,java,f95,ada --enable-java-awt=gtk
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--host=i386-redhat-linux
Thread model: posix
gcc version 4.0.2 20051125 (Red Hat 4.0.2-8)

$ g++ -o test.exe test3.cpp
$ ./test.exe
1
2
3
YOU
OU
U
[zentdd@s5 cpp]$


Maybe you have some mystical notion about _your_ understanding or
definition of the word WORK.

If so - maybe thats all I'd need to clarify what you're talking about.

I don't know if its portable. I don't know if it works all the time
everywhwere. I don't know if its to spec. I don't know if its
dangerous. I don't claim any of those things. And I think it would
likely be impossible to prove many such things via formal proof.

So again - I'm sure that given your definition of the word "Work" - you
are correct. But given the context of your statement - I'm at a loss
for what you are talking about.

Imagine a student compiling this program, running it - turning it in --
and the teacher claiming "it doesn't work - use .... instead." and
givng the student an F.

And how about ... "are you sure you want to do this?" "advances the
pointer" "will do bad things" "even worser".

Does that teach the student anything?

Your post was just noise. The only people that know what you're talking
about ... already knew what you were talking about -- if indeed, you
said anything worth talking about.
 

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

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top