473,397 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

Weird pointer error

I see some really weird output from this program (compiled with GCC
3.3.2 under Linux).

#include <iostream>
using namespace std;

int main() {
char *s;
s = "test1";
cout << "s = " << s << " and &s = " << &s << "\n";

char *s2;
s2 = "foo bar";
cout << "s2 = " << s2 << " and &s2 = " << &s2 << "\n";
cout << "so s = " << s << "\n";

int *i;
*i = 1;
cout << "i = " << *i << " and &i " << &i << "\n"; //could have used
i instead of &i

int j;
j = 4;
cout << "j = " << j << " and &j " << &j << "\n";

return 0;
}

---

BTW: I know I can initialize on definition.

Output of the program is:
s = test1 and &s = 0xbfffe354
s2 = foo bar and &s2 = 0xbfffe350
so s = test1
Segmentation fault (what else, lol)

--
I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them. If I comment
out the s2 part, then the program works (no segfault).

Why would s2 make this problem?

Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?

Thanks in advance,
cmad
Jul 22 '05 #1
10 2029

"Chris Mantoulidis" <cm****@yahoo.com> wrote in message
news:a8**************************@posting.google.c om...
I see some really weird output from this program (compiled with GCC
3.3.2 under Linux).

#include <iostream>
using namespace std;

int main() {
char *s;
s = "test1";
cout << "s = " << s << " and &s = " << &s << "\n";

char *s2;
s2 = "foo bar";
cout << "s2 = " << s2 << " and &s2 = " << &s2 << "\n";
cout << "so s = " << s << "\n";

int *i;
*i = 1;
cout << "i = " << *i << " and &i " << &i << "\n"; //could have used
i instead of &i

int j;
j = 4;
cout << "j = " << j << " and &j " << &j << "\n";

return 0;
}

---

BTW: I know I can initialize on definition.

Output of the program is:
s = test1 and &s = 0xbfffe354
s2 = foo bar and &s2 = 0xbfffe350
so s = test1
Segmentation fault (what else, lol)

--
I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them. So you agree now that pointers are evil :-) (I actually don't).
If I comment
out the s2 part, then the program works (no segfault). It's not s2 that's the trouble in your program. It's i which is pointing to some
garbage address.
s and s2 are const string literals.
Why would s2 make this problem?

Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?

hmm..well you should expect addresses on stack to be in decreasing
order..right?.

-Sharad
Jul 22 '05 #2
Chris Mantoulidis wrote:
I see some really weird output from this program (compiled with GCC
3.3.2 under Linux).

#include <iostream>
using namespace std;

int main() {
char *s;
s = "test1";
The above conversion shouldn't be used. "test1" is of type const
char[7], and you let a pointer to non-const char point to it. That's
dangerous, because it will seem as if you can change the literal, which
you actually can't.
cout << "s = " << s << " and &s = " << &s << "\n";

char *s2;
s2 = "foo bar";
cout << "s2 = " << s2 << " and &s2 = " << &s2 << "\n";
cout << "so s = " << s << "\n";

int *i;
*i = 1;
*i is the integer which the pointer i points to. But the pointer isn't
initialized. It points just into the open sky. The behaviour of the
above assignment is undefined, because it is an attempt to write to
some random memory location that might not even belong to your program.
cout << "i = " << *i << " and &i " << &i << "\n"; //could have used
i instead of &i

int j;
j = 4;
cout << "j = " << j << " and &j " << &j << "\n";

return 0;
}

---

BTW: I know I can initialize on definition.

Output of the program is:
s = test1 and &s = 0xbfffe354
s2 = foo bar and &s2 = 0xbfffe350
so s = test1
Segmentation fault (what else, lol)

--
I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them.
You don't assign to the pointer. You try to assign to what it points to.
If I comment out the s2 part, then the program works (no segfault).

Why would s2 make this problem?
You shouldn't care. The behaviour of your above program is undefined, so
according to the C++ standard, everything can happen. What you observe
above is just one instance of "undefined behaviour". Note that the
result can depend on anything. It might be different on different
compilers or on the same compiler on a different OS or hardware, or
even on the same system with different compiler settings or a newer
version of the same compiler. It isn't worth trying to find out why
something specific happens when you invoke undefined behaviour.
Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?


It is platform dependant.

Jul 22 '05 #3
On Tue, 10 Feb 2004 19:21:50 +0530 in comp.lang.c++, "Sharad Kala"
<no*****************@yahoo.com> was alleged to have written:
I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them.

So you agree now that pointers are evil :-) (I actually don't).


Uninitialized pointers are always evil.

Jul 22 '05 #4
> > If I comment
out the s2 part, then the program works (no segfault). It's not s2 that's the trouble in your program. It's i which is pointing to some
garbage address.
s and s2 are const string literals.


So the way of solving this is by using new (to s, s2 and/or i)? Okay
they're const string literals, so what? Why would s and/or s2 be
deleted before the end of main()?
Why would s2 make this problem?

Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?

hmm..well you should expect addresses on stack to be in decreasing
order..right?.


Why so? I could expect them to be in increasing order :/ In fact I did
expect them to be in increasing order ;) And since I'm a pointer n00b
and newbie, shouldn't you be talking about heap instead of stack? (for
pointers).
-Sharad

Jul 22 '05 #5
> I see some really weird output from this program (compiled with GCC
3.3.2 under Linux). #include <iostream>
using namespace std;

int main() { [snip code referring to "s2"] int *i;
*i = 1; [snip]
return 0;
}

Output of the program is:
Segmentation fault (what else, lol)

I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them. If I comment
out the s2 part, then the program works (no segfault).

Why would s2 make this problem?
You caused UB with the "*i = 1" line. You should not be surprised
by any particular subsequent behaviour (including crashes,
failure to crash, and nasal demons).

The contents of your application's memory (which could determine
i's value before initialization) are affected by the other
allocations and function calls that you make.
You were (un) lucky in that without the s2 code, "i" happened to
point to memory that your platform thinks you are allowed to access,
and furthermore, memory that was not doing anything important,
so your antics did not cause the platform to complain.
Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?
Platform-dependent obviously. It could even give i and j the same address,
if they are never used concurrently, or they could not even have addresses
at all in some situations (eg. register variables)

Finally, you wrote:
cout << "i = " << *i << " and &i " << &i << "\n";
//could have used i instead of &i


You would get different results for "i" as for "&i"
(assuming you first fixed the UB).
Jul 22 '05 #6
#include <iostream>
using namespace std;

int main() {
char *s;
s = "test1";
cout << "s = " << s << " and &s = " << &s << "\n";

char *s2;
s2 = "foo bar";
cout << "s2 = " << s2 << " and &s2 = " << &s2 << "\n";
cout << "so s = " << s << "\n";

int *i;
int k = 1 ;
i = &k ;
cout << "i = " << *i << " and &i " << &i << "\n"; //could have used
i instead of &i

int j;
j = 4;
cout << "j = " << j << " and &j " << &j << "\n";

return 0;
}

cm****@yahoo.com (Chris Mantoulidis) wrote in message news:<a8**************************@posting.google. com>...
I see some really weird output from this program (compiled with GCC
3.3.2 under Linux).

#include <iostream>
using namespace std;

int main() {
char *s;
s = "test1";
cout << "s = " << s << " and &s = " << &s << "\n";

char *s2;
s2 = "foo bar";
cout << "s2 = " << s2 << " and &s2 = " << &s2 << "\n";
cout << "so s = " << s << "\n";

int *i;
*i = 1;
cout << "i = " << *i << " and &i " << &i << "\n"; //could have used
i instead of &i

int j;
j = 4;
cout << "j = " << j << " and &j " << &j << "\n";

return 0;
}

---

BTW: I know I can initialize on definition.

Output of the program is:
s = test1 and &s = 0xbfffe354
s2 = foo bar and &s2 = 0xbfffe350
so s = test1
Segmentation fault (what else, lol)

--
I wrote this program because i wanted to see what happens when I
assign values to pointers when I don't initialize them. If I comment
out the s2 part, then the program works (no segfault).

Why would s2 make this problem?

Oh, as I said, if I remove the s2 part it works fine and j's address
is 4bytes before i (the pointer). So the compiler allocates memory
with decreasing order? Or is this platform dependent?

Thanks in advance,
cmad

Jul 22 '05 #7
> The above conversion shouldn't be used. "test1" is of type const
char[7], and you let a pointer to non-const char point to it. That's
dangerous, because it will seem as if you can change the literal, which
you actually can't.
SO, to use a pointer I have to do one of the following:
1) If I want it to just point at an address (probably a variable's
address) then no need to allocate memory for it (with new).
2) If I want the pointer to have it's own value then I HAVE to use
new.

So with s, I must follow the 2nd rule, since I want s to have its own
value. Why would const char * work? I don't get it. Okay "test1" is of
type const char[], so what? Can't a pointer point at a const value? Or
is that a rule I've never seen? :( I don't get why const char *, would
work better than char *; and it does work better.
*i is the integer which the pointer i points to. But the pointer isn't
initialized. It points just into the open sky. The behaviour of the
above assignment is undefined, because it is an attempt to write to
some random memory location that might not even belong to your program.


Why doesn't the same happen for s or s2?
Jul 22 '05 #8
Chris Mantoulidis wrote:
The above conversion shouldn't be used. "test1" is of type const
char[7], and you let a pointer to non-const char point to it. That's
dangerous, because it will seem as if you can change the literal, which
you actually can't.


SO, to use a pointer I have to do one of the following:
1) If I want it to just point at an address (probably a variable's
address) then no need to allocate memory for it (with new).
2) If I want the pointer to have it's own value then I HAVE to use
new.


no.
A pointer is a variable, just like an int variable is a variable.
A storage to store something there.

The difference is: an int variable holds some number, say 5 or 8 or 6712
while a pointer variable holds an address. Where this address comes from
is of little interest to the pointer variable, it makes no difference.

The prefix & operator is called the address-of operator. It's purpose
is to come up with the address of something.

So in
int i;
i is an int variable. This variable exists somewhere in memory and hence
has an address. This address can be stored in a pointer variable, since the
whole job of pointers variables is to store addresses.

int* Ptr;

Ptr = &i;

read the last line as: get the address of i and store it in Ptr.

Another possibility would be to use 'new'.
new's purpose is to allocate and reserve some storage somewhere in memory.
To inform you where in memory the reservation has taken place, it gives you
the address of that memory area. Again: There is an address and there is
the pointer variable.

Ptr = new int;

--------------------------------------------------------
What other operations besides storing an address can you do with pointers?
For one there is the dereference operator '*'. When written as a postfix
operator to a pointer, it means: fetch the address stored in that pointer
variable, because the actual operation will take place at whatever address
this will be.

*Ptr = 5;

read as: take the Ptr variable. In it you will find the address in memory
where the 5 should be stored.
Now in your specific case:

int* i;
*i = 2;

Where does i point to? What is the address stored in i? We don't know, the
address is completely unspecified. So assigning the 2 to the memory cell
with that unspecified address is a thing you must not do.
--
Karl Heinz Buchegger, GASCAD GmbH
Teichstrasse 2
A-4595 Waldneukirchen
Tel ++43/7258/7545-0 Fax ++43/7258/7545-99
email: kb******@gascad.at Web: www.gascad.com

Fuer sehr grosse Werte von 2 gilt: 2 + 2 = 5
Jul 22 '05 #9
Chris Mantoulidis wrote:
The above conversion shouldn't be used. "test1" is of type const
char[7], and you let a pointer to non-const char point to it. That's
dangerous, because it will seem as if you can change the literal,
which you actually can't.
SO, to use a pointer I have to do one of the following:
1) If I want it to just point at an address (probably a variable's
address) then no need to allocate memory for it (with new).
2) If I want the pointer to have it's own value then I HAVE to use
new.


That's not "it's own value". A pointer is just a variable that stores an
address. It doesn't in itself have any other value than that address.
You can let a pointer point at anthing that has the right type. In the
above case 1, you'd just create a variable and let a pointer point to
it. That variable's life time is limited to the end of the block it was
defined in, so you can't do anything with its address afterwards. If
you want an object to live longer than that, you need to dynamically
allocate it, which is case 2.
Since the int you create with new is not a variable (variables always
have a name), you cannot access it directly. Therefore, 'new' returns
the address of the new object, and you can store that address in your
pointer. Still the object that it points to cannot be seen as the
pointer's "own value". What a pointer really points to doesn't matter
if you access an object through it, as long as that is an existing
object of the according type.
So with s, I must follow the 2nd rule, since I want s to have its own
value. Why would const char * work? I don't get it. Okay "test1" is of
type const char[], so what? Can't a pointer point at a const value? Or
is that a rule I've never seen? :( I don't get why const char *, would
work better than char *; and it does work better.


There are four constness modifications for a pointer. The pointer itself
can be const or non-const (i.e. it can't/can be modified to point to
another address than it was initialized with), and the object that it
points to can be const or non-const (meaning you can't/can modify that
object through the pointer). So for a pointer to char, that is:

char* modifyable pointer to a modifyable char
const char* modifyable pointer to a constant char
char* const constant pointer to modifiable char
const char* const constant pointer to a constant char

Normally, if your object is already const, you can only let a pointer to
const point to it. So:

const char c('X');
char* p = &c;

won't work, because c is const, and you can't let a pointer to non-const
point to it, since that would relax the constness. Now string literals
are a special case. They are of type array of const char, and thus
cannot be modified. But there exists a special conversion rule that
makes it possible to still let a pointer to non-const char point to it.
The reason why that rule exists is historical, and mostly for
compatibility with C. You should however not make use of this, since it
can lead to errors that the compiler can't detect. E.g.:

char* hello = "Hello, world\n";
int main()
{
hello[1] = 'X';
}

The above code is illegal, because the string literal that 'hello'
points to must not be modified. But since you let a pointer to
non-const char point to it, the compiler won't detect that error.
*i is the integer which the pointer i points to. But the pointer
isn't initialized. It points just into the open sky. The behaviour of
the above assignment is undefined, because it is an attempt to write
to some random memory location that might not even belong to your
program.


Why doesn't the same happen for s or s2?


Because both s and s2 are assigned the address of something before they
are used. You wrote:

**char**s;
**s*=*"test1";

This will let s point to the first character of the literal "test1".
Same for s2. But you don't do this for i. You create it uninitialized
and then try to assign to the integer that it points to without
actually letting it point to an integer before.

Jul 22 '05 #10
Thank you Karl and Rolf ;) That's a lot of explaining and now it's a
LOT more clear to me :) Thank you again

cmad
Jul 22 '05 #11

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

Similar topics

2
by: Tim Johansson | last post by:
When i run my program, i get the following: "Exiting due to signal SIGSEGV General Protection Fault at eip=0001cdc0 eax=00000009 ebx=000ca110 ecx=000ca110 edx=00000000 esi=0000160e edi=00000009...
4
by: alex323 | last post by:
Hey. I must have an array that can be resized dynamically. I have coded an implementation of it using malloc/realloc, but I am getting a runtime error as seen below in GDB: *** glibc detected...
4
by: jedi200581 | last post by:
Hi, I'm new at python as I just started to learn it, but I found out something weird. I have wrote a little program to compute Mersenne number: # Snipet on def is_prime n: for i in range(2,...
3
by: Joe Van Dyk | last post by:
I'm compiling some code on a IRIX compiler (MIPSpro Compilers: Version 7.4.2m) with all warnings turned on, and I'm getting some of these warnings: cc-3649 CC: ERROR at end of source all...
12
by: syn1kk | last post by:
1: float (*data); 2: data = malloc(31 * sizeof(data)); 3: data = VARIABLE; Question 1: The variable data is a float pointer? Question 2: When the is used. Does that mean it is an...
12
by: MQ.john | last post by:
//Working Example: #include <stdio.h> #include <time.h> int main () { time_t rawtime; /* define rawtime as time_t */ time ( &rawtime );
14
by: WStoreyII | last post by:
the following code is supposed to read a whole line upto a new line char from a file. however it does not work. it is producing weird results. please help. I had error checking in there for...
7
by: dtschoepe | last post by:
Hi, I am working on a project for school and I am trying to get my head around something weird. I have a function setup which is used to get an input from stdin and a piece of memory is created...
4
by: harsh.murari | last post by:
In the example below, a single object (Network) is implementing 2 interfaces (INetworkA and INetworkB). Both of these interfaces derive from the IBase interface (similar to the IUnknown interface...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
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,...
0
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,...

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.