#### Archived

This topic is now archived and is closed to further replies.

# I need help with this please

This topic is 5668 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

okay, i am doing a chapter in a book on C++ to help me understand pointers (AK!) and i did one of the sample problems. the problem is that one of the variables is acting up...
void main() {
char *str = "I'm afraid I can't let you do that Dave.";
char *ch = &str[0];

for (unsigned int i = 0; i
this is what the book gives, but when i ran it, i get a general protection fault. After an hour of trying different things, i got it work by defining
char *str = "I'm afraid I can't let you do that Dave.";
as
char str[] = "I'm afriad I can't let you do that Dave.";
It works and everything, i am just curious as to what happened. Why did the first declartion not work? I have other examples, where defining a string like that worked, but here it f'ed up.
''Can I go back?''
''No. But if you could, would you really want to?''
- mr. neo
[edited by - mtrneo3 on June 5, 2002 4:36:34 PM]


##### Share on other sites
be carefully working with strings and pointers...
when u declare char str[] = "blabla...";
your compiler put by itself the END OF STRING, i mean the carcter NULL or ''\0'';
when u declare char *str = "blabla..."; that doesn''t happen..
So your function strlen(char *); CAN''T find how big is your string... (it counts untill find NULL). when you try to use *s or *e will occur an error: u are trying to acess a NOT ALLOCED MEMORY!

i hope u understand...

##### Share on other sites
That''s completely false.

At least in vc++

I just tested and compiled this code:

  #include <iostream>#include <string.h>using namespace std;int main(int argc,char** argv){	char* blah = "This is a test.";	cout << strlen(blah) << endl;	return 0;}

Works flawlessly.

##### Share on other sites
akiinao: ch and str point to the same memory location after the initial assignment, and strlen will most definitely work with any one of them.

mtrneo3: The only explanation I can think of is this. When you declare str as ''char *str'', str is a pointer that points to a string that is stored in constant segment. Since you don''t have write access to constant memory, you get access violation when you''re trying to change str. With the second declaration, however, actual memory is allocated for str and that memory is initialized with your string. This memory is writeable, and your program runs fine. Your first declaration should be ''const char *str'' to indicate that the pointer points to constant memory.

I suppose that with proper optimizations,

const char *str1 = "Some string";
const char *str2 = "Some string";

will point to the same memory location, since "Some string" is assumed to be constant. This may lead to serious problems if you''re trying to modify data pointed to by either str1 or str2. However, in this case:

char str1[] = "Some string";
char str2[] = "Some string";

str1 and str2 will point to different memory areas, and each one will have its own copy of "Some string."

for (unsigned int i = 0; i<strlen(str); i++)

is better replaced with this while loop:

while (*ch)

##### Share on other sites
ur right indirectX. i''ve check that riht now.
char *str = "blah" --> *str = {''b'',''l'',''a'',''h'',''\0''}

##### Share on other sites
Unfortunately I too have encountered this prob before. The problem lies in the windows api header and library files -- more recent versions don''t support that modifying of pointers and stuff, like the older versions do. I would guess that the book you''re using is an obsolete dinosaur (translation:2-5 years old) , so just follow IndirectX''s instructions and you should be fine.

Twilight Dragon
www.freewebz.com/j-world

##### Share on other sites
quote:
Original post by TDragon
The problem lies in the windows api header and library files -- more recent versions don''t support that modifying of pointers and stuff, like the older versions do.

If anything, the "problem" is in stricter memory access permissions, which should depend on the compiler and the runtime operating system.

##### Share on other sites
thanx alot... I think I actually understand some of these replies (wow...)

Indirectx - so what ur saying is that since *str = "bla" only points to the memory location at which the string begins (constant memory?), it actually dosen''t refer to a ''string'' but only three chars located somewhere in memory... did I get that right?

I think I am getting a handle on these things... now just to figure them out without a book

thanks alot guys

''''Can I go back?''''
''''No. But if you could, would you really want to?''''

- mr. neo

##### Share on other sites
Imagine you have two types of memory: constant segment and data segment. When you are referring to a string literal, such as

printf("This is a string literal\n");

that string literal is put into the constant segment. When you are using a variable, such as

int var;
char anotherVar;
char yetAnotherVar[1000];

all of these are put into the data segment. You can only read constant segment, and you have full access to the write segment. Now, if you declare a string pointer like so:

const char *string_ptr = "A string stored in a constant segment";

then four bytes (size of a pointer) are allocated for string_ptr, the variable string_ptr itself is stored in the data segment, and it points to a string that is stored in a constant segment. However, if you declare a char array like so:

char string[] = "This string is stored in data segment";

then string has the sizeof equal to strlen(string)+1, meaning memory in data segment is allocated for the entire string, not just for a 4-byte pointer, and the whole string is copied to that allocated space. Here's my pathetic attempt to graphically represent what I'm talking about:

Takes a while to get the image tags right!

[edited by - IndirectX on June 5, 2002 11:42:10 PM]

##### Share on other sites
wow... with a diagram. Thanx i get that.

''''Can I go back?''''
''''No. But if you could, would you really want to?''''

- mr. neo

##### Share on other sites
This is a little long and doesn't add much, I was just interested and played with it, it would appear that (gcc at least) actually puts both strings into the code segment and then copies the string into the stack to use it, however when dealing with a pointer, it will then go back and attempt to actually modify the pointed to memory (ie in the code segment) - crashing the program, whereas when dealing with the array version it will actually modify the stack.

(asm is in AT&T syntax, operands are reversed from intel and (%eax) means [eax], the rest is hopefully easyish to pick up). No optimizations are on.

      int main(int argc,char** argv){  const char* str1 = "Hello, world";  char str2[] = "Hello again, world";}

gives

gcc2_compiled.:___gnu_compiled_c:        .def    ___main;        .scl    2;      .type   32;     .endef.textLC0:        .ascii "Hello, world\0"LC1:        .ascii "Hello again, world\0"        .align 4.globl _main        .def    _main;  .scl    2;      .type   32;     .endef_main:        pushl %ebp        movl %esp,%ebp        subl $64,%esp pushl %edi pushl %esi call ___main movl$LC0,-4(%ebp)        leal -48(%ebp),%eax        leal -48(%ebp),%edi        movl $LC1,%esi cld movl$4,%ecx        rep        movsl        movsw        movsbL2:        leal -72(%ebp),%esp        popl %esi        popl %edi        leave        ret

Note the two strings are defined in the code (text) segment, does exactly the same without the const qualifier.

Then, trying to modify these:

        int main(int argc,char** argv){  char* str1 = "Hello, world";  char str2[] = "Hello again, world";  str1[0] = 'J';}

Crashes, asm source

        .file   "str1.c"gcc2_compiled.:___gnu_compiled_c:        .def    ___main;        .scl    2;      .type   32;     .endef.textLC0:        .ascii "Hello, world\0"LC1:        .ascii "Hello again, world\0"        .align 4.globl _main        .def    _main;  .scl    2;      .type   32;     .endef_main:        pushl %ebp        movl %esp,%ebp        subl $64,%esp pushl %edi pushl %esi call ___main movl$LC0,-4(%ebp)        leal -48(%ebp),%eax        leal -48(%ebp),%edi        movl $LC1,%esi cld movl$4,%ecx        rep        movsl        movsw        movsb        movl -4(%ebp),%eax        movb 74,(%eax) # eax points to string (pointer is stored on stack at [ebp - 4] earlier)L2: leal -72(%ebp),%esp popl %esi popl %edi leave ret  And attempting to modify str2:  int main(int argc,char** argv){ char* str1 = "Hello, world"; char str2[] = "Hello again, world"; str2[0] = 'J';}  Asm:  .file "str1.c"gcc2_compiled.:___gnu_compiled_c: .def ___main; .scl 2; .type 32; .endef.textLC0: .ascii "Hello, world\0"LC1: .ascii "Hello again, world\0" .align 4.globl _main .def _main; .scl 2; .type 32; .endef_main: pushl %ebp movl %esp,%ebp subl64,%esp        pushl %edi        pushl %esi        call ___main        movl $LC0,-4(%ebp) leal -48(%ebp),%eax leal -48(%ebp),%edi movl$LC1,%esi        cld        movl $4,%ecx rep movsl movsw movsb movb$74,-48(%ebp)L2:        leal -72(%ebp),%esp        popl %esi        popl %edi        leave        ret

EDIT: tags

[edited by - JuNC on June 9, 2002 9:53:47 AM]

• ### Forum Statistics

• Total Topics
628710
• Total Posts
2984323

• 23
• 11
• 9
• 13
• 14