c++ question - need help

Started by
9 comments, last by rip-off 16 years, 3 months ago
ok, so i wrote this program:

#include <iostream>
#include <string>

using namespace std;

int main()
{
	char pa[] = "hello";
	char qa[] = "there";

	*pa = *qa;
	
	cout << *pa << endl;

	cout << *qa << endl;

	return 0;
}
This outputs "t" and "t" which is correct. However, when I change the pa and qa line to this:

char *pa = "hello";
char *qa = "there";
Unknown Exception occurs! Why am i getting this? I thought *pa is the same as pa[]? Can someone please explain me the difference? thanks
Advertisement
This code allocates an array on the stack that's large enough to contain the string assigned to it (I.e. 6 bytes for each [5 + null terminator]) and then fills the array in with the requested data:
char pa[] = "hello";
char qa[] = "there";

This code allocates two pointers on the stack, and initialises them to point at some global memory containing the strings:
char* pa = "hello";
char* qa = "there";

Technically, the second case is wrong, because strings like that are const (I would have throught you'd at least get a compile warning if not an error - what compiler are you using, and what's your warning level set to?). Because the strings pointed to are in global memory, they tend to be in read-only memory, so changing them can cause an access violation.

If you care about the details; strings in the second example are usually stored inside the exe (You'll be able to see them if you look at the exe in notepad). When the OS loader loads the exe file, it chucks the whole thing into memory, and then marks sections of it as read only, executable, etc as required. The strings end up in the .data (or it might be .bss, I can't remember exactly) segment, which is read only.
thanks for the prompt reply.

I used Visual Sudio 2005 with Warning level set to default (which was W3 when I checked the project settings).

There were no warnings when I compiled it.

So, this "Unknown Exception Occurred" really means you are trying to modify the contents of a string in a memory location which is read-only?

I would have thought that it shouldnt matter because I didnt declare the strings as const. This would explain why it works fine if I comment out the *pa = *qa line.

And I picked up this example from this website:
http://www.cplusplus.com/doc/tutorial/pointers.html

under "Pointer initialization" section which talks about allocating a string by using char * terry = "hello";

Also, doesnt the declaration of pa[] and qa[] declare a pointer anyway?
Quote:Original post by bahadir
thanks for the prompt reply.

I used Visual Sudio 2005 with Warning level set to default (which was W3 when I checked the project settings).

There were no warnings when I compiled it.
Hmm, odd. Try setting the warning level to maximum (Which is good practice anyway).

Quote:Original post by bahadir
So, this "Unknown Exception Occurred" really means you are trying to modify the contents of a string in a memory location which is read-only?
Not always, but in this case it looks like it. What's the exact error message? If you're running your app in the debugger you should get a useful error message like "Access violation writing address 0x00402368".

Quote:Original post by bahadir
I would have thought that it shouldnt matter because I didnt declare the strings as const. This would explain why it works fine if I comment out the *pa = *qa line.

And I picked up this example from this website:
http://www.cplusplus.com/doc/tutorial/pointers.html

under "Pointer initialization" section which talks about allocating a string by using char * terry = "hello";
My understanding is that the memory is const and declaring a pointer like that isn't standard (Anyone got a link to the FAQ page that covers this?)

Quote:Original post by bahadir
Also, doesnt the declaration of pa[] and qa[] declare a pointer anyway?
Yes, although not as you think. That declares a pointer called pa (and one called qa), and sets it to point at some memory on the stack. It also allocates 6 bytes of stack space and sets the pointer to point at that stack space. The stack is read/write, so that's fine.
There are subtle differences between pointers and arrays, don't confuse them.

In any case, 99% of the time you are better off using dynamic array/string classes instead of trying to handle stuff manually. Even in your program you #include <string>.

std::string Just WorksTM. It acts how you expect when you pass it to or return in from functions.
thanks Evil. I set the warning level to maximum (W4) and it still doesnt give me any warnings. maybe because I havent installed Service Pack 1 yet i dont know.


I am running it in Debug configuration and when I run the code the VS JIT kicks in and writes:
"An unhandled win32 exception occurred in exe [2136]."

And asks me whether i want to debug or not.


And thanks for the tip rip-off.
rip-off that link you gave me says that an array and pointer is the same thing! Now im really confused!

int foo(int A[], int n) {  return A[n];}int bar(int * A, int n) {  return A[n];}


Here's the assembly MSVC 2003 generates for foo:

mov eax, DWORD PTR _n$[esp-4]
mov ecx, DWORD PTR _A$[esp-4]
mov eax, DWORD PTR [ecx+eax*4]
ret 0


Here's bar:

mov eax, DWORD PTR _n$[esp-4]
mov ecx, DWORD PTR _A$[esp-4]
mov eax, DWORD PTR [ecx+eax*4]
ret 0

I know I can use string to declare it, but when applying for jobs they want me to write it in the conventional "C" style code to show them i know the "inner" workings of how code is executed down to the assembly code level.
You must have misread. The point made in that thread is that pointers and arrays are different. You did read the whole ~3 pages, right [smile].

In the case of foo and bar, both are pointers. In a function argument list, an array declaration is syntactic sugar for a pointer declaration. You can only pass arrays to a function by reference, using the somewhat cryptic notation used in the linked thread.

Read it again, a little more carefully, and see if you come back with the same conclusion. If you have questions, post them here.
ok thanks i will read it properly rather than skimming through it ;)

EDIT:
Ok i read it, so as far as i can tell, an array is a sequence of elements and conserves the type information while a pointer just contains the address location of what its pointing to.
if i try to draw a diagram and show the differences between *pa and pa[] would this be correct?

char pa[] = "hello";

----------------------
| 'h' | 'e' | 'l ' | 'l' | 'o' |
----------------------
0x00a 0x00b 0x00c 0x00d 0x00e

so pa would be at address 0x00a and its contents is 'h'.


while the declaration for:

char *pa = "hello";

----------------------
| 'h' | 'e' | 'l ' | 'l' | 'o' |
----------------------
/|\ 0x00b 0x00c 0x00d 0x00e
|
|
---------
| 0x00a | pa
---------

so pa would be at another address location and its contents is 0x00a?

Is my understanding correct?

This topic is closed to new replies.

Advertisement