Sign in to follow this  
bahadir

c++ question - need help

Recommended Posts

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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
Essentially, yes, that is one difference. There are other differences, mainly that sizeof(array) == sizeof(any element) * num_elements whereas sizeof(pointer) is a constant that isn't related to the size or number of elements in the array. A pointer is reseatable, which means it can be made point at a different array (or even point at a single item).

Quote:

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.


Well, both a pointer and array have a type. But an array has, as part of its type, the number of elements in it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this