复制字符串时没有空格的内存访问不正确

时间:2014-03-02 11:11:30

标签: c string function-calls memory-access

这是我的结构

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;
}

现在,此代码将返回错误的内存访问。 我有很长时间的故障排除,无法解决。 有人想帮助我吗?

1 个答案:

答案 0 :(得分: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字符。

相关问题