【发布时间】:2010-12-24 12:47:55
【问题描述】:
首先,对于任何交叉发帖,我们深表歉意。希望我不会在这里重复一个问题,但我无法在其他地方找到这个问题(通过 Google 和 Stack Overflow)。
这是错误的要点。如果我在代码中的任何位置调用printf、sprintf 或fprintf 来显示浮点数,我会收到SIGSEGV (EXC_BAD_ACCESS) 错误。举个例子吧。
以下抛出错误:
float f = 0.5f;
printf("%f\n",f);
这段代码没有:
float f = 0.5f;
printf("%d\n",f);
我意识到那里有一个隐式转换,但我不关心那个。我只是无法理解为什么打印浮点数与打印整数会引发错误。
注意:部分代码使用malloc创建一些非常大的多维数组。但是,这些打印语句不会以任何方式引用这些数组。这是我如何声明这些数组的示例。
#define X_LEN 20
#define XDOT_LEN 20
#define THETA_LEN 20
#define THETADOT_LEN 20
#define NUM_STATES (X_LEN+1) * (XDOT_LEN+1) * (THETA_LEN+1) * (THETADOT_LEN+1)
#define NUM_ACTS 100
float *states = (float *)malloc(NUM_STATES * sizeof(float));
// as opposed to float states[NUM_STATES] (more memory effecient)
float **q = (float**)malloc(NUM_STATES * sizeof(float*));
for(int i=0; i < NUM_STATES; i++) {
float *a = (float*)malloc(NUM_ACTS * sizeof(float));
for(int j=0; j < NUM_ACTS; j++) {
a[j] = 0.0f;
}
q[i] = a;
}
然后上面的printf 语句出现在代码的后面。
我包含malloc 的原因是因为据我了解,SIGSEGV 与格式不正确的malloc 调用有关。所以,如果数组初始化是导致问题的原因,我想知道:
- 为什么?
- 如何更改
malloc代码来解决此问题?
我已经包含了 OS X 生成的崩溃日志,以防万一帮助任何人。
工艺:极[5453]
路径:{已编辑}
标识符:极
版本: ??? (???)
代码类型:X86-64(本机)
父进程:bash [5441]
日期/时间:2009-12-08 11:38:38.358 -0600
操作系统版本:Mac OS X 10.6.2 (10C540)
报告版本:6
自上次报告以来的间隔:130074 秒
自上次报告以来的崩溃次数:68
自上次报告以来的每个应用程序崩溃:63
匿名 UUID:CA20CF15-8C46-4C85-A793-6C69F9F40140
异常类型:EXC_BAD_ACCESS (SIGSEGV)
异常代码:0x0000000100074f3b 处的 KERN_INVALID_ADDRESS
崩溃的线程:0 调度队列:com.apple.main-thread
线程 0 崩溃:调度队列:com.apple.main-thread
0 libSystem.B.dylib 0x00007fff828d489e __Balloc_D2A + 164
1 libSystem.B.dylib 0x00007fff828d49b8 __d2b_D2A + 45
2 libSystem.B.dylib 0x00007fff828e8c74 __dtoa + 320
3 libSystem.B.dylib 0x00007fff828aa960 __vfprintf + 4980
4 libSystem.B.dylib 0x00007fff828ec7db vfprintf_l + 111
5 libSystem.B.dylib 0x00007fff828ec75e fprintf + 196
6 极 0x00000001000028b5 平衡::sarsa() + 187
7 极 0x0000000100002e54 主 + 49
8 极 0x00000001000010a8 开始 + 52
线程 0 因 X86 线程状态(64 位)而崩溃:
rax:0x00000000000000001 rbx:0x000000010042cca0 rcx:0x000000010042cca8 rdx:0x0000000100074f3b
rdi:0x000000000000000e rsi:0x00007fff5fbfecbc rbp:0x00007fff5fbfeba0 rsp:0x00007fff5fbfeb90
r8: 0x00007fff5fbff0b0 r9: 0x0000000000000000 r10: 0x00000000ffffffff r11: 0x000000010083a40b
r12:0x0000000000000001 r13:0x00007fff5fbfecb8 r14:0x00007fff5fbfecbc r15:0x000000010000363e
撕裂:0x00007fff828d489e rfl:0x0000000000010202 cr2:0x0000000100074f3b
二进制图像:
0x100000000 - 0x100003fff +极点??? (???) {已编辑}
0x7fff5fc00000 - 0x7fff5fc3bdef dyld 132.1 (???) /usr/lib/dyld
0x7fff81697000 - 0x7fff8169bff7 libmathCommon.A.dylib ??? (???) /usr/lib/system/libmathCommon.A.dylib
0x7fff8289c000 - 0x7fff82a5aff7 libSystem.B.dylib ??? (???) /usr/lib/libSystem.B.dylib
0x7fff83c4c000 - 0x7fff83cc9fef libstdc++.6.dylib ??? (???) /usr/lib/libstdc++.6.dylib
0x7ffffffe00000 - 0x7fffffe01fff libSystem.B.dylib ??? (???) /usr/lib/libSystem.B.dylib
型号:MacBookPro4,1,BootROM MBP41.00C1.B03,2 个处理器,Intel Core 2 Duo,2.4 GHz,2 GB,SMC 1.27f2
显卡:NVIDIA GeForce 8600M GT、GeForce 8600M GT、PCIe、256 MB
内存模块:global_name
AirPort:spairport_wireless_card_type_airport_extreme (0x14E4, 0x8C),博通 BCM43xx 1.0 (5.10.91.19)
蓝牙:2.2.4f3版本,2个服务,1个设备,1个传入串口
网络服务:AirPort、AirPort、en1
串行 ATA 设备:日立 HTS542520K9SA00,186.31 GB
并行 ATA 设备:MATSHITADVD-R UJ-867
USB 设备:内置 iSight、0x05ac (Apple Inc.)、0x8502、0xfd400000
USB 设备:Apple 内部键盘/触控板、0x05ac (Apple Inc.)、0x0230、0x5d200000
USB 设备:IR 接收器、0x05ac(Apple Inc.)、0x8242、0x5d100000
USB 设备:BRCM2046 集线器、0x0a5c(博通公司)、0x4500、0x1a100000
USB 设备:蓝牙 USB 主机控制器,0x05ac(Apple Inc.),0x820f,0x1a110000
谢谢。
【问题讨论】:
-
至少你应该检查
malloc()返回的值是非空的 -
对 printf 的调用只会导致代码中其他地方出现问题。这是 C 代码,而不是 C++。
-
提供给 printf() 的内容无关紧要 - 由调用者在调用函数之前适当调整堆栈。这是 C 与 Pascal(被调用函数负责清理堆栈)相比的便利之一,也是调用约定完全不同的原因。
-
请参阅tenouk.com/Bufferoverflowc/Bufferoverflow3.html,了解有关调用函数如何从堆栈中为被调用函数推送和弹出参数的更多信息。
-
你真的应该接受下面给出的建议(多次)并获得 Valgrind。当前版本 (3.5.0) 支持 Mac OS X (10.5.x)。
标签: c malloc printf segmentation-fault