导致分段错误的 Char *strcat 实现
Char *strcat Implementation leading to Segmentation Fault
char *strcat(char*dest, char*src) {
while (dest != '[=10=]') {
*dest++;
}
while (src != '[=10=]') {
*dest++ = *src++;
}
return dest;
}
我一直在 *dest++ = *src++
行遇到分段错误。关于如何解决问题的任何想法?
dest
和 source
永远不会变成 '[=14=]'
如果它们一开始不是空的(或者可能在很长一段时间后才正确,但你可能会 运行 很久以前就内存不足了)。
你应该使用:
while(*dest != '[=10=]'){
dest++;
}
while(*src != '[=10=]'){
*dest++ = *src++;
}
检查指针下的值。
还有一些其他问题:
结果字符串不是null-terminated。
返回一个指向字符串末尾的指针。
正如其他人所说:src
也应该是 const pointer
。
应该这样做:
char *strcat(char *dest, const char *src)
{
char *start_pos = dest;
while(*dest != '[=11=]')
dest++;
while(*src != '[=11=]')
*dest++ = *src++;
*dest = '[=11=]';
return start_pos;
}
次要细节:我会给这个函数取一个不同于标准使用的名称 strcat()
。
您的代码有 4 个问题:
- 您正在比较指向空字符的指针,而不是比较它们指向的字符。由于指针在变为 0 之前需要递增很多次,如果有的话,您正在读取 and/or 写入超出缓冲区末尾的内容,在此之前 from/to 无效内存,因此崩溃。
- 您没有终止目标字符串。
- 你 return 指向目标字符串末尾的指针,而不是原始目标字符串。这可能很有用 API,但您应该为此使用不同的名称。
src
指针应声明为 const char *
以符合此函数的标准声明并允许将指向常量字符串的指针作为源传递。
这是更正后的版本:
char *strcat(char *dest, const char *src) {
char *saved = dest;
while (*dest != '[=10=]') {
dest++;
}
while ((*dest++ = *src++) != '[=10=]') {
continue;
}
return saved;
}
好的:Kernighan 方式:
char *strcat(char *dest, char *src)
{
char *org = dest;
while(*dest++){;}
// at this moment, *dest MUST be pointing to '[=10=]'
while(*dest++ = *src++){;}
// at this moment, *dest MUST be pointing to '[=10=]' agian
return org;
}
更新(礼貌地@chqrlie):
char *strcat(char *dest, char *src)
{
char *org = dest;
for(; *dest; dest++) {;}
// at this moment, dest MUST be pointing to '[=11=]'
while(*dest++ = *src++) {;}
// at this moment, dest points past the '[=11=]', but who cares?
return org;
}
char *strcat(char*dest, char*src) {
while (dest != '[=10=]') {
*dest++;
}
while (src != '[=10=]') {
*dest++ = *src++;
}
return dest;
}
我一直在 *dest++ = *src++
行遇到分段错误。关于如何解决问题的任何想法?
dest
和 source
永远不会变成 '[=14=]'
如果它们一开始不是空的(或者可能在很长一段时间后才正确,但你可能会 运行 很久以前就内存不足了)。
你应该使用:
while(*dest != '[=10=]'){
dest++;
}
while(*src != '[=10=]'){
*dest++ = *src++;
}
检查指针下的值。
还有一些其他问题:
结果字符串不是null-terminated。
返回一个指向字符串末尾的指针。
正如其他人所说:src
也应该是 const pointer
。
应该这样做:
char *strcat(char *dest, const char *src)
{
char *start_pos = dest;
while(*dest != '[=11=]')
dest++;
while(*src != '[=11=]')
*dest++ = *src++;
*dest = '[=11=]';
return start_pos;
}
次要细节:我会给这个函数取一个不同于标准使用的名称 strcat()
。
您的代码有 4 个问题:
- 您正在比较指向空字符的指针,而不是比较它们指向的字符。由于指针在变为 0 之前需要递增很多次,如果有的话,您正在读取 and/or 写入超出缓冲区末尾的内容,在此之前 from/to 无效内存,因此崩溃。
- 您没有终止目标字符串。
- 你 return 指向目标字符串末尾的指针,而不是原始目标字符串。这可能很有用 API,但您应该为此使用不同的名称。
src
指针应声明为const char *
以符合此函数的标准声明并允许将指向常量字符串的指针作为源传递。
这是更正后的版本:
char *strcat(char *dest, const char *src) {
char *saved = dest;
while (*dest != '[=10=]') {
dest++;
}
while ((*dest++ = *src++) != '[=10=]') {
continue;
}
return saved;
}
好的:Kernighan 方式:
char *strcat(char *dest, char *src)
{
char *org = dest;
while(*dest++){;}
// at this moment, *dest MUST be pointing to '[=10=]'
while(*dest++ = *src++){;}
// at this moment, *dest MUST be pointing to '[=10=]' agian
return org;
}
更新(礼貌地@chqrlie):
char *strcat(char *dest, char *src)
{
char *org = dest;
for(; *dest; dest++) {;}
// at this moment, dest MUST be pointing to '[=11=]'
while(*dest++ = *src++) {;}
// at this moment, dest points past the '[=11=]', but who cares?
return org;
}