【问题标题】:Abort trap: 6 in C when using strcpy on MacOS中止陷阱:在 MacOS 上使用 strcpy 时,C 中的 6
【发布时间】:2017-04-30 14:20:38
【问题描述】:

我正在编写一些代码,将字符串作为输入并将其反向返回。

当我输入一个字符串时,我得到一个“abort trap: 6”错误。我认为问题在于我对 strcpy 的使用(误用?),但 GDB 没有帮助,关于此错误和 strcpy 的其他问题也没有帮助我理解为什么会收到此错误。

我在代码中添加了一些 cmets 来解释预期的功能。

感谢您提供的任何帮助或阅读材料!

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

        int main()
        {
            char line[1024];
            fgets(line,sizeof(line),stdin);
            int size = strlen(line);
            for(int I = 0; I <size-I;I++)
            {
                char temp;
                int relative_size = size-I;
                strcpy(&temp,&line[I]);//??copies Ith character of line to temp??
                strcpy(&line[I],&line[relative_size]); //??swaps characters at [I] and [size-I]??
                strcpy(&line[relative_size],&temp); 
            }
            printf("%s", line);
            return 0;
        }

【问题讨论】:

  • int relative_size = size-I; --> int relative_size = size-I-1; , strcpy(&amp;temp,&amp;line[I]); --> temp = line[I]; 等等。
  • @BLUEPIXY 完美运行!非常感谢。

标签: c string runtime-error strcpy


【解决方案1】:

strcpy 不会单独复制字符。它复制字符串。该字符串是字符数,后跟一个 \0 终止字符。

 strcpy(&temp,&line[I]);

以上 strcpy 尝试将字符串从第 I 个字符开始复制到结尾(到达第一个 \0)到 &temp 指定的地址。因为 temp 是单个 char 变量,实际上您正在破坏堆栈框架并将内容意外写入其他变量。

你应该使用这样的东西来获得第 i 个字符

temp = line[I];

【讨论】:

    【解决方案2】:

    strcpy() 不复制单个字符,而是复制整个以 0 结尾的字符串。因此strcpy(&amp;temp, &amp;line[i]); 是“缓冲区溢出”(temp 不是真正的缓冲区),如果line[I] 不是\0。要复制单个字符,只需分配它:

    temp = line[I];
    

    这也适用于以下两个语句。

    【讨论】:

    • 啊,好的。感谢您的帮助!
    【解决方案3】:

    要反转字符串,您需要交换字符串的字符对,不包括终止零。

    标准 C 函数 strcpy 旨在复制字符串。例如,如果变量line 包含字符串"abcd" 并且变量I 等于0,那么这个语句

    strcpy(&temp,&line[I]);
    

    等价于这个语句

    strcpy(&temp,&line[0]);
    

    并尝试将整个字符串复制到仅分配一个字节的内存中,正如从声明中看到的那样

    char temp;
    

    因此,变量temp 之外的内存将被覆盖,进而导致程序的未定义行为。

    因此,您应该分配单独的字符,而不是使用该函数。

    循环可能如下所示

    size_t size = strlen(line);
    
    for (size_t i = 0; i < size - i; i++)
    {
        char temp = line[i];
        line[i] = line[size - i - 1];
        line[size - i - 1] = temp;
    }
    

    考虑到函数fgets 将终止零附加到字符数组(如果它们有足够的内存)。您应该在反转之前将其从字符串中删除。可以通过以下方式完成。

    fgets(line,sizeof(line),stdin);
    line[ strcspn( line, "\n" ) ] = '\0';
    size_t size = strlen(line);
    

    标准函数strlen 也有返回类型size_t。所以变量size最好使用这种类型而不是int类型。

    【讨论】:

      猜你喜欢
      • 2021-04-28
      • 2014-12-13
      • 2017-05-11
      • 2015-09-02
      • 1970-01-01
      • 2015-06-06
      相关资源
      最近更新 更多