Cheetaiean
Cheetaiean

Reputation: 941

What does *(long *) on a string cause a segmentation fault?

Consider one or both of the following 'data' values:

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
//char * data = "21st Century Schizoid Man\0I Talk to the Wind\0Epitaff\0Moonchild\0The Court of the Lavender King";
char data1[93] = {'2','1','s','t',' ','C','e','n','t','u','r','y',' ','S','c','h','i','z','o','i','d',' ','M','a','n','\0','I',' ','T','a','l','k',
't','o',' ','t','h','e',' ','W','i','n','d','\0','E','p','i','t','a','p','h','\0','M','o','o','n','c','h','i','l','d','\0','T','h','e',' ','C',
'o','u','r','t',' ','o','f',' ','t','h','e',' ','C','r','i','m','s','o','n',' ','K','i','n','g','\0'};
char * data = data1;

void main () {

char cVar1;
int iVar3;
int iVar4;

iVar3 = 0; iVar4 = 0;
//cVar1 = *(char *)((long)iVar3 + *(long *)(data + (long)iVar4 * 8));
cVar1 = *(char*)(*(long*)data);
} 

Why does the assignment to cVar1 cause a segmentation fault? I know the *(long *) is at issue as removing it prevents the Seg Fault.

EDIT: A commenter linked a post which suggested it is an alignment issue,however how would one fix this? changing the size of the char array to 96 so that it's size would be divisible by 4 or 8 (the sizes of a long) did not stop the segmentation fault. Many other casting combinations do work:

cVar1 = (char*)(*(long*)data):
cVar1 = *(char*)(long*)data);

for example

Upvotes: 0

Views: 101

Answers (1)

dbush
dbush

Reputation: 224387

This is not so much an issue of alignment as it is an invalid pointer value.

First you have this:

(long*)data

The results in a long * which points to the same memory location as data. Then you dereference the pointer:

*(long*)data

At this point, the C standard states this is undefined behavior. On architectures with more strict alignment requirements this could cause a crash, but on an x86 machine with a 64-bit long, you'll probably end up with a value made up of the first 8 bytes of data with the least significant byte first. This results in a value of 0x6e65432074733132, which if you look closely is the ASCII codes of the first 8 characters in reverse order.

Now you have this:

(char*)(*(long*)data)

Which interprets the value 0x6e65432074733132 as a pointer. Then you attempt to dereference it:

*(char*)(*(long*)data)

The value 0x6e65432074733132 is almost certainly not a valid address, so when you attempt to dereference this value you get a segfault.

Upvotes: 4

Related Questions