如果您使用的是运行某些 OS X 版本的 Mac,则应该同时安装 gcc 和 gdb。如果没有,它们很容易下载和安装。我在 Linux 系统上运行,但下面的步骤和输出在 OS X 上应该类似。
为了在调试器中查看您的源代码,您必须使用-g 选项编译它:gcc -o myprog -g myprog.c。否则,您只会看到生成的机器代码。
此时,您可以正常运行程序并让它转储您将加载到 gdb 中的核心文件,或者在 gdb 中启动程序并逐行执行。
我冒昧地获取了您的代码并从中创建了一个完整的程序:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
int **values;
int i, j;
values = malloc(10 * sizeof(int *));
for (i = 0; i < 10; i++){
for (j = 0; j < 10; j++){
values[i][j] = i * j;
}
}
for (i = 0; i < 10; i++)
printf("%d ", values[i][i]);
printf("\n");
return 0;
}
我们将在启用调试的情况下构建它:
$ gcc -o example -g -std=c99 -pedantic -Wall -Werror example.c
并在 gdb 中启动它:
$ gdb example
GNU gdb (GDB) SUSE (7.1-8.9.1)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/fbgo448/prototypes/coredump/example...done.
(gdb)
我们要做的第一件事是在main处设置一个断点;这将导致程序一进入主函数就暂停:
(gdb) break main
Breakpoint 1 at 0x4005a0: file example.c, line 9.
现在我们将启动在 gdb 环境中运行的程序;它将运行到下一个断点:
(gdb) r
Starting program: /home/fbgo448/prototypes/coredump/example
Breakpoint 1, main () at example.c:9
9 values = malloc(10 * sizeof(int *));
您可以一次执行一行,如下所示:
(gdb) n
10 for (i = 0; i < 10; i++){
您可以检查变量或任意内存位置的内容:
(gdb) p values
$1 = (int **) 0x501010
(gdb) p *values
$2 = (int *) 0x0
(gdb) x/1x 0x501010
0x501010: 0x00000000
(gdb) x/1b 0x501010
0x501010: 0x00
(gdb) x/10b 0x501010
0x501010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x501018: 0x00 0x00
(gdb) x/10x 0x501010
0x501010: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x501018: 0x00 0x00
希望您已经看到了问题,但如果没有,我们可以“继续”程序并让它运行直到失败:
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005e3 in main () at example.c:12
12 values[i][j] = i * j;
您在尝试分配 values[i][j] 时遇到了段错误。我们再来看看:
(gdb) p i
$3 = 0
(gdb) p j
$4 = 0
(gdb) p values
$5 = (int **) 0x501010
(gdb) p values[i]
$6 = (int *) 0x0
(gdb) p values[i][j]
Cannot access memory at address 0x0
其他人已经指出了问题;您为指向int 的10 个指针分配了足够的空间,但您没有为这些指向to 的指针分配任何东西。您在分配过程中缺少一个步骤:
values = malloc( 10 * sizeof *values ); // sizeof *values == sizeof (int *)
if ( values )
{
for ( i = 0; i < 10; i++ )
{
values[i] = malloc( 10 * sizeof *values[i] ); // sizeof *values[i] == sizeof (int)
if ( values[i] )
{
for (j = 0; j < 10; j++ )
{
values[i][j] = i * j;
}
}
}
}
gdb 是一个相当强大的调试器,虽然使用起来有些痛苦。