【问题标题】:Error in output after Loop is caused by strcat?循环后输出错误是由strcat引起的吗?
【发布时间】:2015-10-04 15:02:58
【问题描述】:

我有以下代码在循环中将字符串附加到另一个。

代码

#include<stdio.h>
#include<string.h>

int main(void){
        char src1[] = "name";
        int i;
        for (i=1;i<=5;i++){
                strcat(src1,"opps");
                printf("loop times %d\n",i);
        }
                printf("now src1 is:%s\n",src1);
        return 0;
}

为了调试代码,我在代码中添加了printf 语句并进行了编译。当我运行时,我得到以下结果:

输出

循环次数 1 循环次数 0 循环时间 1886416641 现在 src1 是:nameoppsoppsopps

我的问题是“为什么printf 循环 1886416641 次?”此外,结果也不是我所期望的。有人可以帮我澄清一下吗?

【问题讨论】:

  • 你写的越界。在这种情况下,您将覆盖循环计数器。
  • 与其说“结果也不是我所期望的。”,更有用的是发布所期望的。

标签: c loops strcat


【解决方案1】:

str1 只分配了 5 个字节,strcat 将访问越界,则可能导致未定义的行为。

1886416641这个号码是不小心弄到的。

你必须为str1分配足够的内存才能得到正常的结果。
例如:char src1[32] = "name";

【讨论】:

  • 1886416641 几乎没有是偶然的:它是 0x70706F01,所以 ascii ppo'\1'。这意味着您可能可以从中找出 OP 机器的字节序。
  • 谢谢,我已将内存空间扩展到S1,现在可以使用了。
【解决方案2】:

您的src1[] 不够大。当您附加第二个“opps”时,它会覆盖i。值 1886416641 是十六进制 70706f01:0x70='p',0x70='p',0x6f='o'。

编译器已舍入到下一个 32 位机器字。以字节为单位的堆栈如下所示:

start:        loop1    loop2
src1[]:
    n
    a
    m
    e
    \0        o
    <fill>    p
    <fill>    p
    <fill>    s
i:
    00        \0    o
    00        00    p
    00        00    p
    01        02    s
                    \0

(堆栈不准确;某些元素实际上是颠倒的-以它为例)

【讨论】:

  • 要明确“当您附加第二个“opps”时,它会覆盖 i”是 srtrcat() 写入超出 src1[] 导致的未定义行为示例。它确实解释了 OP 的结果 - 在另一天/平台等上可能会有所不同。
【解决方案3】:

根据strcat()man page,只是为已经存在的答案添加一些细节,

char *strcat(char *dest, const char *src);

strcat() 函数将src 字符串附加到dest 字符串,覆盖dest 末尾的终止空字节('\0'),然后添加终止空字节。字符串不能重叠,**并且dest 字符串必须有足够的空间用于结果。如果dest 不够大,程序行为是不可预测的; [...]

如果您的最终字符串的长度超过目标可以存储的长度,您将访问超出限制的内存,从而导致undefined behavior

在您的代码中,src1 从初始化字符串的长度中获取其大小。稍后,如果您想存储更长的存储空间,则需要在开始时分配更多存储空间,例如

char src1[128] = "name";

或类似的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多