堆栈上的字符数组导致段错误

char array on stack causes seg fault

这可能是预料之中的,但我只是好奇 how/why 会发生这种情况。

当我尝试使用在本地 char * foo = "\xFF\xFF..." 声明的 char * 作为整数时,它会出现段错误。但是,如果我使用 malloc,当我尝试访问它时,它运行得非常好。为什么会这样?

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

int main(int argc, char **argv)
{
  unsigned char *buf = malloc(16);
  memcpy(buf, "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 16);
  //unsigned char *buf = "\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; // seg faults if you sue this instead

  uint64_t *k  = (uint64_t *) buf;
  uint64_t *k2 = (uint64_t *) (buf + 8);
  uint64_t i  = 1000000000;

  printf("-k =%" PRIu64 "\n", *k);
  printf("-k2=%" PRIu64 "\n", *k2);

  printf("Iter * %" PRIu64  "\n", i);
  for (uint64_t c = 0; c < i; ++c)
    {
      *k  += 1;
      *k2 -= 1;
    }

  printf("-k =%" PRIu64 "\n", *k);
  printf("-k2=%" PRIu64 "\n", *k2);

  return 0;

}

输出:

easytiger $ gcc -std=c99 tar.c -Wall -O2 ; time ./a.out
-k =0
-k2=18446744073709551615
Iter * 1000000000
-k =1000000000
-k2=18446744072709551615

不能保证字符串文字将存储在可写内存页中。这意味着 for 循环中的 *k += 1 操作可能会尝试写入只读内存。另一方面,由 malloc 分配的内存将始终是可写的。

对于这种形式的定义:

unsigned char *buf = "some string";

buf 指向存储在内存只读部分中的静态字符串。当您尝试写入它时,会出现段错误。

通过使用mallocbuf指向的内存是可写的。

字符串文字是不可变的。您不得修改存储在那里的数据。曾经.

即使在现在的 C 语言中,我们也通过将 const 放入指针类型来使这一点变得清晰和可诊断。

C++ 实际上需要它。