Chr*_*len 6 c valgrind overlap strcpy
背景:我有一个模仿的小例程,fgets(character, 2, fp)除了它从字符串而不是流中获取字符.newBuff是动态分配的字符串,作为参数传递,字符声明为char character[2].
常规:
character[0] = newBuff[0];
character[1] = '\0';
strcpy(newBuff, newBuff+1);
Run Code Online (Sandbox Code Playgroud)
strcpy在从中读取每个字符时复制信息丢失.
问题:Valgrind确实警告我这个活动,"源和目标重叠在strcpy(0x419b818,0x419b819)".
我应该担心这个警告吗?
asv*_*kau 11
可能标准没有规定当这些缓冲区重叠时会发生什么.所以是的,valgrind抱怨这个是正确的.
实际上,您 很可能会strcpy从左到右(例如while (*dst++ = *src++);)按顺序找到您的副本,并且这不是问题.但它仍然不正确,并且在与其他C库一起运行时可能会出现问题.
一种标准正确的写入方式是:
memmove(newBuff, newBuff+1, strlen(newBuff));
Run Code Online (Sandbox Code Playgroud)
因为memmove被定义为处理重叠.(虽然在这里你最终会遍历字符串两次,一次检查长度和一次复制.我也采取了一个捷径,因为strlen(newBuff)应该相等strlen(newBuff+1)+1,这是我最初写的.)
是的,你也应该担心你的功能在病理上有不好的表现(O(n^2)对于应该是的任务O(n)).每次读取一个角色时,都会通过角色移回字符串的全部内容,这是一个巨大的浪费时间.相反,你应该只保留一个指向当前位置的指针并递增该指针.
您发现自己需要memmove或等效的情况(在重叠的缓冲区之间复制)几乎总是表明存在设计缺陷.通常,它不仅仅是实现中的缺陷,而是界面中的缺陷.
| 归档时间: |
|
| 查看次数: |
5412 次 |
| 最近记录: |