简体   繁体   English

C语言中的内存保护

[英]Memory protection in C

Is there no memory protection in C ? C中没有内存保护吗? Can a process edit any memory space ? 进程可以编辑任何内存空间吗? how does C determines a memory is allocated is it stored somewhere ? C如何确定分配的内存是否存储在某个地方? For instance : 例如 :

int a[2] = {2,3};
int *ptrA = &a;

int b = 10;
int *ptrB = &b;

printf("%d ",*(ptrA+1009));
*(ptrA+1009) = 10;
printf("%d \n",*(ptrA+1009));

printf("%d ",*(ptrB+1009));
*(ptrB+1009) = 10;
printf("%d\n",*(ptrB+1009));

Here pointer to unallocated memory has read/write access. 在这里,指向未分配内存的指针具有读/写访问权限。 Snippet complies and runs with a warning. 片段符合并运行并显示警告。 Is it undefined behaviour/machine dependent ? 它是不确定的行为/机器相关的吗?

Memory protection doesn't mean what you think it means: It's measures to stop a process from accessing memory it shouldn't access. 内存保护并不意味着您想像的是什么:采取措施可以阻止进程访问不应访问的内存。 However, processes of course can access their own memory, which C/C++ and a lot of other languages let you do. 但是,进程当然可以访问它们自己的内存,而C / C ++和许多其他语言可以使您做到这一点。

Here pointer to unallocated memory has read/write access. 在这里,指向未分配内存的指针具有读/写访问权限。

dereferencing a pointer into unallocated is what we call a bug in your software :) However, it's totally OK that your compiler lets you do that. 将指针取消引用到未分配状态就是我们所说的软件错误:)但是,编译器允许您这样做完全可以。 C/C++ don't have your back , if you want to juggle with pointers, by all means, do. C / C ++ 不会退缩 ,如果您想与指针打交道,那就一定要这样做。 You will provoke undefined behaviour or segmentation faults, if the addresses you try to access are not mapped in your process' memory (that's memory protection at work), but these languages let you do that. 如果您尝试访问的地址未映射到进程的内存中(即工作中的内存保护 ),则将引发未定义的行为或分段错误,但是使用这些语言,您可以这样做。

No, there is no built-in memory protection in C, but using a pointer to access memory outside the object to which it points -- as your code does -- invokes undefined behavior. 不,C语言没有内置的内存保护功能,但是使用指针访问它所指向的对象之外的内存(就像您的代码一样)会调用未定义的行为。 "Undefined behavior" does not mean that the program must fail or emit any particular diagnostic. “未定义的行为”并不意味着程序必须失败或发出任何特定的诊断。 Those are permissible results, but if they were required then that would be defined behavior. 这些是允许的结果,但是如果需要这些结果,那么这将是定义的行为。

The C/C++ standards don't have any requirements for dereferencing addresses. C / C ++标准对取消引用地址没有任何要求。 They provide access to raw memory so are general enough to be valid on bare metal, virtual memory systems, etc... So, as far as the language is concerned, it is perfectly valid to access a variable through an offset of a pointer to another variable or any memory reference in general. 它们提供对原始内存的访问,因此足够通用,可以在裸机,虚拟内存系统等上有效。因此,就语言而言,通过指向指针的偏移量访问变量是完全有效的通常是另一个变量或任何内存引用。 It is undefined behavior though, so the actual behavior generally depends on the runtime and/or operating system and/or hardware. 但是,它是未定义的行为,因此实际行为通常取决于运行时和/或操作系统和/或硬件。

This compiler is free to add bounds checks to all memory references though. 该编译器可以自由地将边界检查添加到所有内存引用。 However, the general benefit of C/C++ is raw access to memory. 但是,C / C ++的一般好处是对内存的原始访问。 Runtime bounds checking is generally too expensive to be practical for production use, but it is often used in debugging to find these types of errors. 运行时边界检查通常太昂贵,无法实际用于生产环境,但通常用于调试中以查找这些类型的错误。 For a good example of runtime bounds checking, see valgrind or clang address sanitizer. 有关运行时边界检查的良好示例,请参见valgrindclang地址清理器。

Most compilers will provide basic static bounds check warnings though. 大多数编译器会提供基本的静态边界检查警告。 You can ( should ) generally turn them into errors using a switch like -Werror . 通常,您可以( 应该 )使用-Werror这样的开关将它们转换为错误。 There are also various static analyzers that will identify potential and verifiable out of bounds accesses. 还有各种静态分析器可以识别潜在且可验证的越界访问。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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