473,698 Members | 2,616 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2055

"Chris Mantoulidis" <cm****@yahoo.c om> wrote in message
news:a8******** *************** ***@posting.goo gle.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. 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.co m (Chris Mantoulidis) wrote in message news:<a8******* *************** ****@posting.go ogle.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

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

Similar topics

2
2391
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 ebp=000c99f8 esp=000c99e0 program=C:\TEST.EXE cs: sel=01a7 base=029d0000 limit=000dffff ds: sel=01af base=029d0000 limit=000dffff es: sel=01af base=029d0000 limit=000dffff fs: sel=017f base=00006ca0 limit=0000ffff
4
4008
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 *** realloc(): invalid next size: 0x08054828 *** Program received signal SIGABRT, Aborted. 0xffffe410 in __kernel_vsyscall () (gdb) bt
4
1478
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, n): if (n % i) == 0:
3
1913
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 virtual functions for class "std::__Named_exception" inline: static virtual table generated cc-3649 CC: ERROR at end of source
12
2404
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 array of float pointers? What does it mean? Question 3: Or does it mean that there are 16384 floats allocated with
12
1923
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
2716
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 mallocs and ect, but i removed them to help me debug. thanks. #include <stdio.h> #include <stdlib.h> #include <string.h> void freadl ( FILE *stream, char **string ) {
7
2008
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 on the heap using malloc. This input is then run through a regex and another test. The result is passed back as a char pointer to the program for further processing The first time I call this function, it performs normally. However,
4
1626
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 of the COM world). Network object also implements the QueryInterface methods from IBase interface. In the main function, I am doing a QueryInterface on the INetworkA interface. It returns me the pointer to the second interface INetworkB. On...
0
9170
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8902
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8873
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7740
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6528
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4372
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4623
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
2339
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2007
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.