0

这是我的结构

typedef struct {
    int  startIndex;
    int length;
    char *rawString;
}Tokenizer;

我有一个复制字符串的功能(这将修剪空间)

void copyStringWithoutSpace(char *source,char *destination )
{
    int i =0 ,j=0;

    destination = malloc (sizeof(char)*strlen(source));
    for(i=0;i<strlen(source);i++)
    {
        if(!(source[i]==' ')||(source[i]=='\t'))
        {
            destination[j] =source[i];
            j++;
        }
    }
    destination[j]='\0';
}

这是调用 copyStringWithoutSpace 的函数

Tokenizer *initTokenizer(char *expression)
{
    int i =0, j=0;
    Tokenizer *newTokenizer = malloc (sizeof(Tokenizer));
    copyStringWithoutSpace(expression, newTokenizer->rawString);
    newTokenizer ->startIndex =0;
    newTokenizer ->length =strlen(newTokenizer->rawString);
    return newTokenizer;
}

现在,此代码将返回错误的内存访问。我故障排除了这么久,无法解决。有人愿意帮助我吗?

4

1 回答 1

1

注意 C 字符串是以 NULL 字符结尾的,并且这个字符没有被 考虑strlen,这意味着它在内存中的大小实际上是strlen(source) + 1

您需要做的是像这样分配缓冲区:

destination = malloc (strlen(source) + 1);

sizeof(char)C 标准保证为 1,因此您可以安全地省略它。

此外,您正在修改函数destination内部变量的值,这意味着从函数外部看不到copyStringWithoutSpace新分配的内存,这将导致内存泄漏。

您需要返回指针,并具有以下签名:

char * copyStringWithoutSpace(char *source)

或者:

void copyStringWithoutSpace(char *source, char ** destination)

你必须像这样分配内存:

*destination = malloc (strlen(source) + 1);

这里的另一个错误是:if(!(source[i]==' ')||(source[i]=='\t'))

由于运算符优先级,这不会做你想做的事。在这里,否定运算符仅适用于以下一对括号,这意味着您的测试可以拼写为:

如果 source[i] 不是空格,或者 source[i] 是表格

你应该这样写:

if (source[i] != ' ' && source[i] != '\t')

哪个更清楚,不是吗?

然后,正如评论中指出的那样,strlen在每次迭代时调用效率非常低,因为需要迭代整个字符串直到 NULL 字符。

于 2014-03-02T11:35:52.843 回答