存储器引用错误例
回答
我相信(告诉我,如果我错了),因为结构被存储为一件大事,引用超出范围的数组索引将调出结构中下一个元素的数据。
在内存中,有一个int,另一个int,然后是一个double。它们全都相邻存放。
让我们举个简单的例子:
typedef struct {
int X[2];
int Y;
} struct_t;
如果我们访问元素#3(X [2])的struct的,我们会得到Y,就像这样:
void main() {
volatile struct_t s;
s.X[0] = 99;
s.X[1] = 98;
s.Y = 97;
printf("%i", s.X[2]);
}
该输出97,因为struct_t的第三个int大小的块是97.
现在让我们看看你的问题。 struct_t的前四个字节属于int数组。最后八个属于双。 fun()
将最后八个设置为3.14,根据我的编译器,它等于0x51EB851F。然后它将A的第I个字节设置为0x4000。因此,通过写入“第三个”数组元素(与double重叠)。这将覆盖double,并改变它的值。
通过写入第6个字节,您开始写出内存不足,这给您段错误。不过,GCC有另一个怪癖。 CPU可以更快地访问偶数地址上对齐的数据,因此GCC会将填充插入到结构中。另外,int
和double
的大小也会随着系统的不同而变化,这使得本例在不同的系统上输出不同的东西。
从会计观点来看,您没有关闭,而是从您调用的C标准观点*未定义行为*尝试访问定义范围之外的数组元素。 –
这是真的。 CSAPP课程正在访问一个超出界限的数组来展示一个观点,并且可能不是旨在鼓励导致未定义行为的代码(至少,我希望如此)。 –
未定义的行为通常在stackoverflow中被忽视。我认为这有点失控,这是一个完全教育的例子,只要你添加免责声明,不同的系统可能会表现出不同的行为,并且解释显示在特定情况下发生了什么 – Leeor
- 1. 无效存储器引用(SIGSEGV)错误
- 2. 存储器错误
- 3. MongoDB - 存储引擎错误
- 4. 从存储引擎得到错误-1
- 5. Mysql'从存储引擎出现错误-1'错误
- 6. MySQL错误:“1030 - 遇到错误-1从存储引擎”
- 7. Oracle共享存储器错误
- 8. Boost ::信号存储器访问错误
- 9. Sklearn高斯回归 - 存储器错误
- 10. LINQ到存储过程的“错误的存储属性”错误
- 11. 对象引用一个未保存的瞬态实例错误
- 12. 错误:对象引用未保存的瞬态实例
- 13. JVM崩溃,错误= '无法分配存储器'(错误= 12)
- 14. C++:右值引用存储器
- 15. 如何在SQLCLR存储过程中保存webservice引用实例?
- 16. 编程接收到的信号SIGSEGV:分段错误 - 无效的存储器引用。 Backtrace为这个错误:
- 17. Azure存储Blob -com.microsoft.azure.storage.core.Utility错误
- 18. Xcode存储Git错误
- 19. Oracle:存储过程错误
- 20. MySQL存储过程错误
- 21. MySQL存储过程错误
- 22. JBoss本地存储错误
- 23. 错误数据存储
- 24. MySQL存储过程错误
- 25. 本地存储错误
- 26. 部署prestashop存储错误
- 27. 存储过程的错误
- 28. 会话存储错误只
- 29. SQL存储过程错误
- 30. ADO.NET存储过程错误
在本例中考虑int的sizeof,double的sizeof以及保证可写的内存。 –
你真正的问题是什么?你不明白什么? –
'double fun(int i){if(i < 0 || i > 1){.. handle error ..} ...}'? –