valcind错误与strcpy

时间:2012-12-16 16:31:17

标签: c linux string memory valgrind

此代码应该从userInput以null结尾的字符串

中提取路径
  /* begin createPath */
    static inline char* createPath(char * userInput)
    {/* This function retuns the path from the userInput */
            int pathStringLength = 0;
            char *buf = userInput;
            while(*(buf++) != ' ')
                    pathStringLength++;
            char *path = malloc(pathStringLength+1);
            strncpy(path, userInput, pathStringLength);
    //      memcpy(path, userInput, pathStringLength);
            path[pathStringLength+1] = '\0';        
            return path;
    }
    /* end createPath */

根据valgrind,此代码有错误:

> ==2919== Conditional jump or move depends on uninitialised value(s)
> ==2919==    at 0x400A87: createPath (in /home/aral/learn/myShell/myShell)
> ==2919==    by 0x400A4C: parseInput (in /home/aral/learn/myShell/myShell)
> ==2919==    by 0x4009C3: main (in /home/aral/learn/myShell/myShell)
> ==2919== 
> ==2919== Invalid write of size 1
> ==2919==    at 0x400AC3: createPath (in /home/aral/learn/myShell/myShell)
> ==2919==    by 0x400A4C: parseInput (in /home/aral/learn/myShell/myShell)
> ==2919==    by 0x4009C3: main (in /home/aral/learn/myShell/myShell)

在stackoverflow上搜索类似的问题,有些人谈到添加空终止符,而其他人提到使用memcpy而不是strcpy;无论如何我添加了一个null并尝试使用memcpy但没有任何改进,valgrind一直在抱怨。

我到底做错了什么?我该如何解决?

3 个答案:

答案 0 :(得分:6)

path[pathStringLength+1] = '\0';

错了。那是最后一个字节。你的意思是:

path[pathStringLength] = '\0';

如果输入字符串没有空格,您还将有一个缓冲区溢出。检查循环中的null终止符,并在遇到循环时终止。我会这样写:

while (*buf != ' ' && *buf != '\0')
{
    pathStringLength++;
    buff++;
}

对于它的价值,我认为memcpy可能是更好的选择。一旦你确切地知道需要复制多少文本,你也可以将它搞砸。不需要查找空终止符的字符串函数。您修复代码后,已经检查过它们。

您应该检查malloc的返回值。

答案 1 :(得分:2)

您写信至path[pathStringLength+1]而不是path[pathStringLength] - 索引从0开始。

答案 2 :(得分:0)

strncpy不是更安全的方法strcpyman strncpy说,

The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.

所以为了保护这一点,不要NULL终止于练习帮助,

strncpy(des, src, len)
des[len -1] = '\0';