You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C90环境下程序出现段错误(Segmentation fault)的原因及字符串解析方案咨询

Segmentation Fault in getFirstTok Function & String Parsing Options for a Two-Pass Assembler

I'm working on a two-pass assembler and need to parse strings by delimiters: first extracting the command (like "add" separated by spaces), then extracting operands (like "r3" and "r5" separated by commas). I tried testing my getFirstTok function but hit a segmentation fault (exit code 139, SIGSEGV). Here's my code:

main.c:

int main() { 
    char *x = "add r3,r5"; 
    char *t; 
    char **end; 
    t = getFirstTok(x,end); 
    printf("%s",t); 
}

getFirstTok implementation:

/* getFirstTok function returns a pointer to the start of the first token. */
/* Also makes *endOfTok (if it's not NULL) to point at the last char after the token. */
char *getFirstTok(char *str, char **endOfTok) { 
    char *tokStart = str; 
    char *tokEnd = NULL; 
    /* Trim the start */ 
    trimLeftStr(&tokStart); 
    /* Find the end of the first word */ 
    tokEnd = tokStart; 
    while (*tokEnd != '\0' && !isspace(*tokEnd)) { 
        tokEnd++; 
    } 
    /* Add \0 at the end if needed */ 
    if (*tokEnd != '\0') { 
        *tokEnd = '\0'; 
        tokEnd++; 
    } 
    /* Make *endOfTok (if it's not NULL) to point at the last char after the token */ 
    if (endOfTok) { 
        *endOfTok = tokEnd; 
    } 
    return tokStart; 
}

What's causing the segmentation fault, and would strtok be a better fit for this parsing task?


Why You're Getting a Segmentation Fault

There are two critical issues in your code leading to the crash:

  1. Modifying a read-only string literal
    Your x is initialized as char *x = "add r3,r5";—this points to a string literal stored in read-only memory (usually the .rodata section of your executable). When getFirstTok tries to run *tokEnd = '\0';, it's attempting to write to this protected region, which triggers a SIGSEGV (segmentation fault).

    Fix this by declaring x as a writable character array instead:

    char x[] = "add r3,r5";
    

    This copies the literal into a stack-allocated, writable array, allowing the necessary modifications.

  2. Uninitialized double pointer end
    In main, you declare char **end; but never initialize it—this is a wild pointer pointing to random, invalid memory. When getFirstTok executes *endOfTok = tokEnd;, it's writing to this undefined address, which also causes a segmentation fault.

    Fix this by declaring a single pointer and passing its address to getFirstTok:

    char *end; // Single pointer, not double
    t = getFirstTok(x, &end);
    

Is strtok a Better Fit?

strtok can work for your assembler parsing needs, but it has tradeoffs you should consider:

  • Pros: It handles basic tokenization by delimiters out of the box, which would simplify your code for both space-separated commands and comma-separated operands. You can switch delimiters by calling strtok(NULL, ",") after initial tokenization with spaces.
  • Cons:
    • It's not thread-safe (uses static internal state), which might be an issue if you ever expand your assembler to use concurrency. For a thread-safe alternative, use strtok_r (POSIX) or strtok_s (C11).
    • It modifies the original string (replaces delimiters with \0), just like your current getFirstTok function—so you still need to ensure you're working with writable strings (not literals).
    • It skips consecutive delimiters automatically (which might be desired for spaces, but could be problematic if your assembler allows optional commas or other edge cases) and doesn't handle empty tokens well.

For an assembler, where you might need precise control over parsing (e.g., handling comments, whitespace variations, or specific syntax rules), a fixed custom parser (like your getFirstTok with the above fixes) might be more flexible. You could extend it to accept a set of delimiters instead of just spaces, making it reusable for both command and operand parsing.

内容的提问来源于stack exchange,提问作者Dvir Peretz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 07:49:07