简体   繁体   中英

Segmentation fault when accessing specific pointer

I'm trying to code my own malloc and free in C for a project. For the most part, it's going fine but I can't wrap my head around a strange Segmentation Fault it's giving me. I reproduced the code that was giving the error in a simplified form:

#include <stdio.h>

#define MEMORY_SIZE 4096
static char memory[MEMORY_SIZE];

typedef struct metaData{
    unsigned short isFree; //1 if free, 0 if allocated
    unsigned short size;
} metaData;

int main(){
    metaData *head = (metaData *) memory;
    printf("%d\n", (head+2031)->size);
    printf("%d\n", (head+2032)->size);
    puts("Segmentation up here???");

    return 0;
}

memory is a static array of chars of size 4096. The first printf prints out a 0. But the next printf is a segfault. I am able to manipulate the metaData struct at every pointer up until head+2032 . Does anyone have any idea why?

Pointer arithmetic in C is performed in base units of the size of the pointed-to type . Your head is a pointer to a metaData structure, which has a size of 2 × sizeof(unsigned short) . Assuming (as is likely, but not certain) that an unsigned short has a size of 2 bytes on your platform, then that "base unit" will be 4 bytes.

Thus, when the head + 2031 calculation is made, the value of 4 × 2031 (which is 8124) will be added to the address in head to give the result of that expression. So, with the following ->size operator, you are attempting to reference memory that is 8,126 bytes 1 from the location of the beginning of your memory array – but that array is declared as only 4096 bytes ( sizeof(char) is, by definition, 1 byte).

Accessing memory beyond the declared size of an array is undefined behaviour (UB); once you have invoked such UB (as you do in both printf calls), many different things can happen, and in unpredictable ways. A "segmentation fault" (trying to read or write memory to which your program does not have access) is one possible manifestation of UB. (Another possible manifestation is that no error is reported and the program appears to work properly; in many people's opinion, that's the worst kind!)


1 8,124 bytes will be the offset of the start of the potentially pointed-to meteData structure; because size is preceded by another unsigned short member, then another two bytes will be added.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM