访问特定指针时出现分段错误
Segmentation fault when accessing specific pointer
我正尝试在 C 中为一个项目编写我自己的 malloc 和 free。在大多数情况下,一切都很好,但我无法解决它给我的一个奇怪的分段错误。我以简化形式重现了给出错误的代码:
#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
是一个大小为 4096 的静态字符数组。第一个 printf
打印出 0。但下一个 printf
是一个段错误。我能够在 head+2032
之前的每个指针处操作 metaData
结构。有人知道为什么吗?
C 中的指针运算以 pointed-to 类型 的 大小的基本单位执行。您的 head
是指向 metaData
结构的指针,其大小为 2 × sizeof(unsigned short)
。假设(很可能,但不确定)unsigned short
在您的平台上的大小为 2 个字节,那么“基本单位”将为 4 个字节。
因此,当进行 head + 2031
计算时,4 × 2031
的值(即 8124)将被添加到 head
中的地址以给出该表达式的结果.因此,使用以下 ->size
运算符,您试图从 memory
数组的开头位置引用 8,126 字节 1 的内存——但是数组被声明为只有 4096 字节(sizeof(char)
根据定义是 1 个字节)。
访问超出数组声明大小的内存是未定义行为 (UB);一旦你调用了这样的 UB(就像你在 both printf
调用中所做的那样),许多不同的事情就会发生,并且以不可预测的方式发生。 “分段错误”(尝试读取或写入您的程序无权访问的内存)是 UB 的一种可能表现形式。 (另一种可能的表现是没有报错,程序看起来正常运行,在很多人看来,这是最糟糕的一种!)
1 8,124 字节将是潜在 pointed-to meteData
结构开始的偏移量;因为 size
前面有另一个 unsigned short
成员,那么将添加另外两个字节。
我正尝试在 C 中为一个项目编写我自己的 malloc 和 free。在大多数情况下,一切都很好,但我无法解决它给我的一个奇怪的分段错误。我以简化形式重现了给出错误的代码:
#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
是一个大小为 4096 的静态字符数组。第一个 printf
打印出 0。但下一个 printf
是一个段错误。我能够在 head+2032
之前的每个指针处操作 metaData
结构。有人知道为什么吗?
C 中的指针运算以 pointed-to 类型 的 大小的基本单位执行。您的 head
是指向 metaData
结构的指针,其大小为 2 × sizeof(unsigned short)
。假设(很可能,但不确定)unsigned short
在您的平台上的大小为 2 个字节,那么“基本单位”将为 4 个字节。
因此,当进行 head + 2031
计算时,4 × 2031
的值(即 8124)将被添加到 head
中的地址以给出该表达式的结果.因此,使用以下 ->size
运算符,您试图从 memory
数组的开头位置引用 8,126 字节 1 的内存——但是数组被声明为只有 4096 字节(sizeof(char)
根据定义是 1 个字节)。
访问超出数组声明大小的内存是未定义行为 (UB);一旦你调用了这样的 UB(就像你在 both printf
调用中所做的那样),许多不同的事情就会发生,并且以不可预测的方式发生。 “分段错误”(尝试读取或写入您的程序无权访问的内存)是 UB 的一种可能表现形式。 (另一种可能的表现是没有报错,程序看起来正常运行,在很多人看来,这是最糟糕的一种!)
1 8,124 字节将是潜在 pointed-to meteData
结构开始的偏移量;因为 size
前面有另一个 unsigned short
成员,那么将添加另外两个字节。