我有以下代码:

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

int main (int argc, char** argv) {

   *(volatile uint8_t*)0x12345678u = 1;
   int var = *(volatile uint8_t*)0x12345678;
   printf("%i", var);
   printf("%i", &var);

   return (EXIT_SUCCESS);
}


我想看到一个1以及我先前指定的那个int的地址。但是,当由gcc在bash中进行编译时,将仅显示“命令终止”而没有任何错误。有人知道为什么吗?

PS:我是C的新手,所以只是尝试一下。

最佳答案

你在做什么:

*(volatile uint8_t*)0x12345678u = 1;
int var = *(volatile uint8_t*)0x12345678;


是完全错误的。

您无法保证可以访问任意地址,例如0x12345678,更不用说程序可写了。换句话说,您不能将值设置为任意地址并期望它起作用。至少可以说这是未定义的行为,并且很可能会由于操作系统阻止您触摸您不拥有的内存而导致程序崩溃。

尝试运行程序时收到的“命令已终止”恰好是因为操作系统阻止程序访问不允许访问的内存位置。您的程序在执行任何操作之前都会被杀死。



如果您使用的是Linux,则可以使用mmap函数在(几乎)任意地址处请求一个内存页,然后再访问它(请参见man mmap)。这是一个实现所需功能的示例程序:

#include <sys/mman.h>
#include <stdio.h>

#define WANTED_ADDRESS (void *)0x12345000
#define WANTED_OFFSET 0x678 // 0x12345000 + 0x678 = 0x12345678

int main(void) {
    // Request a memory page starting at 0x12345000 of 0x1000 (4096) bytes.
    unsigned char *mem = mmap(WANTED_ADDRESS, 0x1000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    // Check if the OS correctly granted your program the requested page.
    if (mem != WANTED_ADDRESS) {
        perror("mmap failed");
        return 1;
    }

    // Get a pointer inside that page.
    int *ptr = (int *)(mem + WANTED_OFFSET); // 0x12345678

    // Write to it.
    *ptr = 123;

    // Inspect the results.
    printf("Value  : %d\n", *ptr);
    printf("Address: %p\n", ptr);

    return 0;
}

关于c - 为什么在任意存储位置设置值不起作用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59831042/

10-11 21:41