0

Possible Duplicate:
Why do I get a segmentation fault when writing to a string?

I am new to C/C++, I'm trying to learn it, I have created the following function but it throws an exception, when I'm trying to assign the uppercase value to *string: Unhandled exception at 0x00411820 in CPP1.exe: 0xC0000005: Access violation writing location 0x00417754.

void ToUpper(char* string)
{
    while(*string != '\0')
    {
        if(*string >= 97 && *string <= 122)
        {
            int symbol = *string;
            *string = symbol - 32;
        }
        string++;
    }
}

Usage:

char* x = "text"; 
ToUpper(x); 

Could you please help me?

Community
  • 1
  • 1
Eugene
  • 1,515
  • 1
  • 13
  • 23

7 Answers7

3

change

char* x = "text"; 

to

char x[] = "text"; 

DONE

billz
  • 44,644
  • 9
  • 83
  • 100
  • Great, it works, but could you please explain why x[] works and char* [] doesn't, or point me to some resource where I can find it? – Eugene Nov 07 '12 at 09:05
  • 1
    read this link: http://msdn.microsoft.com/en-us/library/69ze775t(v=vs.80).aspx – billz Nov 07 '12 at 09:11
  • String literal resides in read only location and cannot be modified... – billz Nov 07 '12 at 09:18
2

Never try to change a const character string. Always use character arrays for this sort of manipulation.

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
1

Memory for "text" will be allocated in .readonly section.

char* x = "text"; 

Tyring to alter read-only section is undefined behaviour.

use gcc -S filename.c to view the assembly code. This gives you more idea about whereabouts of "text".

Like others suggested, I suggest to use char x[] = "text" instead.

Jeyaram
  • 9,158
  • 7
  • 41
  • 63
1
main()
{
    char *a = "text";
    char *x = malloc(strlen(a)+1); 
    strcpy(x,a);
    ToUpper(x);
    // ToUpper(a); // Fails
    printf("%s %s\n",a,x);
}

Output: text TEXT

ToUpper(a) fails, because the string is replaced in a protected memory area (in the middle of the code most likely, as at least 64-bit x86-processors have [rip] -relative addressing mode, which makes it lucrative to place data in between code lines...

Also char x[]="text"; works, because now the complete array of x is placed in the stack. In case of char *x = "text"; only the pointer is placed on stack, but the content points to restricted (read-only) memory.

Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • Since the string length is known at compile-time, there is absolutely no point in using malloc. And if you do, call free(). – Lundin Nov 07 '12 at 09:55
1

It is an error to try to modify a string literal by a pointer:

void f()
{
   char * p = "Naee";
   p[2] = 'm'; // error: assignment to const; result is undefined
}

Having string literals constant allows for significant optimizations in the storage allocation and access. If you want a string that you can modify modify, you must copy the characters into an array:

void f()
{
   char p [] = "Eero"; 
   p [0] = 'Z'; // ok
}
Klaus78
  • 11,648
  • 5
  • 32
  • 28
0

You can use like this no need to create symbol varible

*string=*string-32;

but pass array to the function in calling environment rather passing string literal

so

char * str[] ="hello";
ToUpper(str);
Omkant
  • 9,018
  • 8
  • 39
  • 59
-1

You have to type cast the value in the assignment statement.

*string = *(char *)symbol - 32;

Sankar Mani
  • 168
  • 3
  • It doesn't solve anything, but it adds another major bug, causing the program to crash even harder. – Lundin Nov 07 '12 at 09:54