簡體   English   中英

C-函數未在輸入字符串的末尾終止,從而導致分段錯誤

[英]C - Function not terminating at end of input string leading to segmentation fault

免責聲明:這是家庭作業的一部分,但不是全部。

我的任務是創建一個“令牌生成器”對象,該對象可通過對TKGetNextToken的每次調用返回一次來檢索由空格分隔的令牌,並對返回的令牌執行一系列操作。

但是,TKGetNextToken函數的行為不正常。 應該發生的是:

  1. 前進輸入字符串,直到找到非空格字符。
  2. 繼續在輸入字符串中前進,直到遇到空格或NULL(指示字符串的末尾),然后將字符添加到新的c字符串中
  3. 如果遇到空格,則返回c字符串,並將字符串中的當前位置保存在TokenizerT結構中。
  4. 如果遇到NULL,則返回c字符串,並將NULL存儲在TokenizerT結構中,以便對TKGetNextToken的所有后續調用均返回NULL。

但是,該函數不會在字符串的結尾處停止,而是會直接吹過去,並打印出內存中的所有內容,直到程序崩潰為止。 我不知道為什么會這樣。

這是代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct TokenizerT_ {
    char *currentToken;
};

typedef struct TokenizerT_ TokenizerT;


char *TKGetNextToken(TokenizerT *tk) {
    char *cp = tk->currentToken;

    while (cp != NULL && isspace(*cp)) {
        cp++;
    }

    if (cp == NULL) {
        tk->currentToken = NULL;
        return NULL;
    }

    int size = 0;
    char *token = malloc(sizeof(char));

    while (cp != NULL && !isspace(*cp)) {
        size++;
        token = realloc(token, size * sizeof(char));
        token[size - 1] = *cp;
        cp++;
    }

    token = realloc(token, (size + 1) * sizeof(char));
    token[size] = NULL;

    tk->currentToken = cp;
    return token;
}

TokenizerT *TKCreate(char *ts) {
    TokenizerT *tokenizer = malloc(sizeof(TokenizerT));
    tokenizer->currentToken = ts;

    return tokenizer;
}

void TKDestroy(TokenizerT *tk) {
    free(tk);
}

int main(int argc, char **argv) {

    TokenizerT *tok = TKCreate(argv[1]);
    char *token = TKGetNextToken(tok);

    while (token) {
        printf("\'%s\'\n", token);
        token = TKGetNextToken(tok);
    }

    TKDestroy(tok);
    return 0;
}

這是給定命令行參數“ 100 200 300 400”的示例輸出。 很明顯,它是從輸入字符串之外的內存中打印的。

'100'
'200'
'300'
'400'
''
'╘jÉ'
'╘hÉ'
''
''
''
''
''

並從gdb輸出

Program received signal SIGSEGV, Segmentation fault.
0x00401476 in TKGetNextToken (tk=0x701720) at test.c:28
28          while (cp != NULL && !isspace(*cp)) {
(gdb) backtrace
#0  0x00401476 in TKGetNextToken (tk=0x701720) at test.c:28
#1  0x0040151e in main (argc=2, argv=0x700cf0) at test.c:60

在您的兩個while循環中,條件應包括對null字符的測試。 用於“在字符串末尾沒有遇到空字符”的適當測試是*cp ,因此使用:

while ( cp != NULL && *cp && !isspace( *cp ) )

我感覺到cp != NULL測試是一個沒有令牌的測試,在這種情況下,應該將它們從while循環中排除掉。 如果那是錯誤的,並且它們是字符串結尾測試,則應將它們替換為*cp測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM