【问题标题】:C Segmentation Fault when accessing a char array index访问 char 数组索引时出现 C 分段错误
【发布时间】:2011-05-20 13:10:42
【问题描述】:

我正在编写一个反馈循环,它接收用户命令并根据收到的命令处理参数。到目前为止,我的函数如下所示:

//main loop of the program that keeps repeating, which each cycle taking in one user input
 void mainLoop(){

char input[100]; // initial command
char reg[2]; // registers R1-R7 and PC
char value[20]; // register value
char breakStatus[20]; // can be either "set" or clear"
char breakAddress[80]; // address of break point in hex


//Retrieve user input
printf("Enter a command: ");
scanf("%s", &input);

//Process user input:

//set (completed)
if(strcasecmp(input, "set") == 0){
    scanf("%s", &reg);
    scanf("%s", &value);    
    set(reg, value);
    printf("register value is %s\n", value);
    printf("value[0] is %x\n", value[0]);
    //printf("Setting %s to %s!\n", reg, value);
}

//break (something's wrong here)
else if(strcasecmp(input, "break") == 0){
    scanf("%s", &breakStatus);
    scanf("%s", &breakAddress);

    printf("breakStatus is %s\n", breakStatus);
    printf("breakStatus[0] is %c\n", breakStatus[0]);
    //printf("%sing break point at address %s\n", breakStatus, breakAddress);
    executeBreak(breakStatus, breakAddress);

}


//error (completed)
else
    printf("Error: %s is not a valid command.\n", input);

 }

我的问题是,每当我尝试访问 breakAddress[index] 时,都会遇到分段错误。当我尝试 printf-ing breakStatus 和 breakAddress 时,它们都保存了预期值(输入示例是 break set x0001,其中 breakStatus = "set" 和 breakAddress = "x0001")。

我知道如果我使用 %c 或 printf("breakStatus[0] is %c\n", breakStatus[0]); 的说明符,它会返回一个有效值。但是,我将 breakStatus 和 breakAddress 传递给另一个函数,并在该函数中检查是否 breakAddress[0] == 'x',我立即收到分段错误。

我不确定如何处理。我尝试将 breakAddress[0] 转换为 char ,但仍然遇到相同的错误。

真正让我困惑的是,我几乎以完全相同的方式对我的 Set 部分进行了编码(相同的 char[] 初始化,相同的 scanf 进程),当我尝试从其中一个变量中检索索引时,它工作得非常好。

以下是我的部分 set() 和 executeBreak() 函数供参考:

void set(char* reg, char* val){
    if(val[0] == 'x'){ // no segmentation fault
    sscanf(val+1, "%x", &registers[r]); 
}

void executeBreak(char* stat, char* add){
    if(!(add[0] == 'x')){ // segmentation fault here (tried casting as char also)
    printf("Error: invalid break address");
    return;
    }
}

如果有人能提供一些关于为什么我在一个函数中出现分段错误而在另一个函数中没有出现分段错误的见解,我们将不胜感激。

编辑:摆脱了在我的 printf 语句中使用 %s ,因为这并不是我的问题所在。理想情况下,我想知道为什么 val[0] 在函数中起作用而 add[0] 不起作用,因为它们被赋予了相同类型的参数。

【问题讨论】:

  • 您没有检查或强制执行字符串长度。如果文本格式不完全正确,这很容易让您感到不安。
  • @DeadMG:那不是void main()

标签: c segmentation-fault


【解决方案1】:

注意编译器警告! :)

您已经定义了char breakStatus[20];,即一个字符数组。然后,在 printf 语句中,你得到了printf("...%s...", breakStatus[0]);

%s 格式化代码需要一个指向字符串的指针。但是,breakStatus[0] 是一个字符值。编译器会警告您如何解决该问题:它将 char 值转换为 char * 指针(char 值 = 0 => 指针地址为 0)。假设 char 值恰好为零,那么整个事情就神奇地变成了一个 NULL 指针。试图取消引用一个 NULL 指针(或者一个 0xff 指针,也许......这个值本质上是随机的,毕竟)几乎不可避免地会导致一个段错误。

(更新:弗拉德所说的......“你的意思是:%c”)

【讨论】:

  • 我明白,但是当 breakStatus 作为参数传递给另一个函数时,如何仍将 breakStatus[0] 提取为字符?我试过:字符检查; sscanf(breakStatus[0], "%c", &check);但我遇到了另一个错误。
  • 也许添加一个修复方法是在故障行中用%c 替换%s 是个好主意。
  • @Alice:为什么不只是check = breakStatus[0]
  • 已修复。事实证明,编译器放错了括号,导致了大多数问题(尽管您的建议仍然很有帮助)。哇,我讨厌通宵达旦地写代码……
【解决方案2】:

使用 gdb 代替调试打印:

#gdb ./myprog
(gdb) r

当程序以 SIGSEGV 停止时,查看堆栈跟踪:

(gdb) bt

【讨论】:

    猜你喜欢
    • 2020-04-09
    • 2014-01-05
    • 2017-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-07
    • 1970-01-01
    相关资源
    最近更新 更多