创建子字符串的 C 错误 - 可能是内存错误?

C bug with creating a substring - possibly a memory error?

我是 C 的新手,想知道是否可以得到一些帮助!我已经处理这个错误 15 个小时了。

所以,这个程序是一个分词器。

基本上,该程序应该接受一个字符串,或者 "token stream," 并将其分解为 "tokens." A "token" 是一个字符串,可以是单词、十六进制整数、八进制int、十进制 int、浮点 int 或符号。

我发布的代码只是出错的代码,我程序的另一部分是创建令牌的代码。

下面代码的工作原理是这样的:它需要一个 "token stream",然后从该流中找到下一个标记。完成后,它将创建 "token stream" 减去新标记的子字符串,并创建 return 作为新的 "token stream."

本质上,当字符串 "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /" 被传递时,程序将正确执行所有操作,但 "jlhg kl(/j jlkh 'no thank you' /" 传递时除外。一旦通过我的程序,就会创建一个 "jlhg" 令牌,但然后它会再次添加到令牌流的 end 中。因此,要分解的新令牌流变为 " kl(/j jlkh 'no thank you' / jlhg",其中 jlhg 被添加到末尾,之前没有。它再次做同样奇怪的事情,紧接着,但用 "kl" 代替。

它只在非常奇怪的情况下才会这样做,所以我不确定原因。我在我的程序中放置了 print 语句,一切正常进行,除了看似无处不在,程序只会在最后添加这些语句。这就是为什么我觉得它 可能 是内存问题,但我完全不知道从这里去哪里。

任何帮助将不胜感激!!!!

编辑:如果你传递字符串 "array[xyz ] += pi 3.14159e-10 A12B" 输出应该是:

字数"array"

左大括号“[

字数"xyz"

右大括号"]"

plusequals "+="

字数"pi"

浮动“3.14159e-10”

字数"A12B"

我的 TokenizerT 是这样的:

struct TokenizerT_
{
    char *tokenType;
    char *token;
};

typedef struct TokenizerT_ TokenizerT;

相关代码:

/*
* TKNewStream takes two TokenizerT objects. 
* It will locate the index of the end   of the last token, 
* and create a substring with the new string to be tokenized.
* @tokenStream: old token stream
* @newToken: new token created from old token stream
*
*/

char *TKGetNextStream(char *tokenStream, char *newToken)
{
    int i,
        index = 0,
        count = 0;

    char last = newToken[strlen(newToken)-1];

    for(i = 0; i < strlen(newToken); i++)
    {
        if(newToken[i] == last)
        {
            count++;
        }
    }

    for(i = 0; i < strlen(tokenStream); i++)
    {
        if(tokenStream[i] == last && count == 1)
        {
            index = i + 1;
            break;
        }
        else if(tokenStream[i] == last)
        {
            count--;
        }
    }

    char *ret = malloc(sizeof(char)*(strlen(tokenStream) - index));

    for(i = 0; i < strlen(tokenStream) - index; i++)
    {
        ret[i] = tokenStream[i+index];
    }

    return ret;
}

/*
* This is my main
*/
int main(int argc, char **argv)
{

    char *string = "0x4356/*abdc 0777 */[]87656879jlhg kl(/j jlkh 'no thank you' /";

    TokenizerT *newToken = malloc(sizeof(struct TokenizerT_)),
               *tokenStream = malloc(sizeof(struct TokenizerT_));  

    tokenStream->token = string;

    while(newToken != NULL)
    {
        newToken = TKCreate(TKGetNextToken(tokenStream));

        if(newToken != NULL)
        {
            tokenStream->token = TKGetNextStream(tokenStream->token,
                                                 newToken->token);

            printf("%s \"%s\"\n",
                   newToken->tokenType,
                   newToken->token);
        }
    }

    TKDestroy(newToken);

    return 0;

}

ret 中创建的字符串未正确以 null 结尾。因此,所有处理字符串的函数都将假定它继续进行,直到恰好在分配的内存之后找到下一个随机零字节。

要解决此问题,请为 ret 再分配一个 space 字节并将其设置为零,或使用 strdup() 等现有函数复制字符串:

ret = strdup(tokenStream + index);