微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何保护内存 – strncat?

function(char *a,char *b) { char newStr[100]; strncpy(newStr,a,sizeof(newStr)); //Line 1 - copy no more than 100 bytes strncat(newStr,b,(sizeof(newStr) - strlen(newStr))); //Line 2 - ? newStr[99] = NULL; //Line 3 - null terminate string }

第2行:正确指定100 个字节减去从a复制过来的strlen以确保我不复制100个字节?

谢谢。

单窗口的风格不同于系统的风格

Visual Studio 2010运行时检查失败#3

改变基于Windows版本的控件的视觉风格

如何在C#中使用Windows Metro Style应用程序的屏幕?

Linux内核标识符中前导和后缀下划线的含义是什么?

这几乎是正确的。 首先,NUL终止线:

newStr[99] = NULL;

是错的。

strncat总是NUL-teriminates,第三个参数是写入的最大字节数, 不包括NUL。

假设,如果strncat没有NUL终止,该行的问题是它总是写入数组的最后一个元素,即使实际的字符串可能会更短。 如果a和b是“你好”和“世界!”,最后的数组将是:

H |é| L | L | O |,| | W | O | R |升| d |!| G | I | B | C |ë| R | I | S | H

gibberish表示在这些位置上的数组的先前内容。 只有在99年之后,大部分这些未初始化的残余物之后,才会有一个NUL。

编辑:另外,基思是正确的关于strncpy 。 他的功能是部分正确的,但第二个函数可能会溢出缓冲区,因为它没有考虑到已经存在的字符串。 两行合并可以写199个字符(包括NUL)。

另外,我错误包括NUL在内的第三个参数。 这留给我们(从基思的修改):

void function(char *a,char *b) { char newStr[100]; /* Make newStr an empty string so you can catenate onto it */ newStr[0] = ''; strncat(newStr,sizeof newStr - 1); strncat(newStr,sizeof newStr - strlen(newStr) - 1); /* Presumably you do something with newStr here */ }

strncpy()不会做你可能认为它做的事情。

strncat()是strcat()一个“更安全”版本,可以让你指定目标数组的大小。

strncpy() 不是 strcpy()的相应“安全”版本。 如果目标数组太大,则strncpy()将填充空字符; 99%的时间是不必要的,因为你只需要一个''来标记一个字符串的结尾。 更糟糕的是,如果目标数组太小, strncpy()会复制尽可能多的字符, 并使目标不被终止 。

strncpy()是为早期Unix系统用来存储文件名的一个模糊的数据结构而设计的。 一个文件名被存储在一个固定长度的14字节缓冲区中,填充了空字节。 如果文件名正好是14个字符,则不会有空终止符。 这不是一个字符串 。

在不太可能的情况下,这是你想要的那种数据结构,那么strncpy()就是这样。 否则,不要使用它; 确认目标足够大后,使用strcpy() 。

以下是我可以写这个函数方法

void function(char *a,char *b) { char newStr[100]; /* Make newStr an empty string so you can concatenate onto it */ newStr[0] = ''; strncat(newStr,sizeof newStr - 1); /* edited */ strncat(newStr,sizeof newStr - strlen(newStr) - 1); /* edited */ /* Presumably you do something with newStr here */ }

笔记:

声明该函数的返回类型。 如果你没有明确地声明它,那么你的编译器可能会认为int ,但这是糟糕的风格和过时的语言特性。

避免strncat() 。

我用'' ,而不是NULL ,以空字符串结束。 NULL是一个空指针常量; 不要用它来表示空字符 。

这里有一个很大的低效率:第二个strncat()必须从newStr的开头重新扫描。 对于少量的短字符串,这不是什么大问题,但是大量的字符串被连接到一个大的目标数组中,会导致严重的减速。 有办法解决这个问题,但是它们要么是非标准的( strlcpy() , strlcat() ),要么是不方便的。

编辑 :感谢马修指出我的代码中的错误。 我想我已经修好了 如果我用新的错误取代了旧的错误,我相信我可以指望某人打我。

另一种方法是:

snprintf(newStr,sizeof newStr,"%s%s",b);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐