Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Segmentation fault - char pointer

In the code below, the line:

*end = *front;

gives a segmentation fault. I asked a similar question here but I'm not sure if this is because I have two copies of num. Please explain why it's seg-faulting. Thank you.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* getPalin(char* num);

int main()
{
    char* num = (char*)malloc(100);

    num = "123456";

    printf("%s\n", getPalin(num) );

    return 0;
}

char* getPalin(char* num)
{
    int length = strlen(num);

    if ( length % 2 == 0 )
    {
        char* front = num;
        char* end = num + strlen(num) - 1;  //pointer to end

        while( front != num + (length/2) )  //pointers not middle yet
        {
            *end = *front;

            printf("%c", *end);

            front++;
            end--;
        }
    }

    return num;
}
like image 535
Mike Anderson Avatar asked Jun 03 '09 06:06

Mike Anderson


3 Answers

These two lines:

char* num = (char*)malloc(100);
num = "123456";

have the following effect.

The first allocates 100 bytes and sets num to point to those bytes.

The second changes num to point to the string "123456" which is almost certainly in read-only memory.

Any attempt to change the contents of read-only memory will result in a segmentation violation. You need to copy the string into the malloc'd num before attempting to change it, with:

strcpy (num, "123456");

That's the line you should have where you currently have:

num = "123456";
like image 114
paxdiablo Avatar answered Nov 12 '22 21:11

paxdiablo


Use

strncpy(num, "123456", 100);

instead of

num = "123456";
like image 42
Konstantin Avatar answered Nov 12 '22 20:11

Konstantin


As per Konstantin's answer.

You have already allocated memory for num with the malloc statement.

If you hadn't then you could get away with:

char* num = "123456";

Which would define and allocate memory on the fly but it would most likely be allocated as a constant and thus read only.

Using strncpy rather than strcpy to copy "123456" will ensure that any extra space beyond the end of string null terminator is also initialised to null, as long as you specify n as being 100 (for your example). Otherwise without initialising the memory allocated by malloc to null (memset(num, 0, 100)) then it is conceivable that you could step beyond the end of the string.

Oh almost forgot. It is advisable to use strcpy_s or strncpy_s as they are more secure, although for your code it won't matter.

like image 43
ChrisBD Avatar answered Nov 12 '22 19:11

ChrisBD