垃圾与strcpy和strcat

时间:2015-06-02 12:27:09

标签: c malloc strcpy strcat

我正在linux中做一个客户端服务器项目,我需要连接一些字符串。

我在Windows中的visual studio上尝试了我的代码并且工作正常,但是linux它给了我一些垃圾。我有这个功能:

char* concat(char s1[], char s2[])
{
    int tam = 0;
    tam = strlen(s1);
    tam += strlen(s2);
    char *resultado =  malloc(sizeof(char) * tam) ;
    strcpy(resultado, s1); 
    strcat(resultado, s2); 
    return resultado;
}

我读到问题是'\0'缺失了,我已经这样做了:

 char* concat(char s1[], char s2[])
{
    int tam = 0;
    tam = strlen(s1);
    tam += strlen(s2);
    char *resultado =  malloc(sizeof(char) * tam) ;
    resultado[tam+1] = '\0';
    strcpy(resultado, s1); 
    strcat(resultado, s2); 
    return resultado;
}

前4次我调用它运行的函数(垃圾消失了),但它给了我`malloc():内存损坏

任何人都可以帮助我?

3 个答案:

答案 0 :(得分:5)

您没有为nul终结器分配空间,这是一个非常常见的错误。

<强>建议

  1. 根据定义,不要使用sizeof(char) 1。
  2. 检查malloc()是否未返回NULL
  3. 始终记住nul字节。
  4. 所以你的代码会像这样修复

    char *resultado =  malloc(1 + tam);
    if (resultado == NULL)
        pleaseDoNotUse_resultado();
    

    另外,请注意这一行

    resultado[tam + 1] = '\0';
    

    有多个问题

    1. tam + 1我们在分配的区块之外。
    2. 您不需要这样做,strcpy()会为您完成。
    3. 在这种情况下使用strcat()strcpy()效率很低,因为您已经知道要复制多少字节,这个

      char *concat(char *s1, char *s2)
      {
          size_t l1;
          size_t l2;
          char  *resultado
      
          if ((s1 == NULL) || (s2 == NULL))
              return NULL;
          l1 = strlen(s1);
          l2 = strlen(s2);
          resultado =  malloc(1 + l1 + l2) ;
          if (resultado == NULL)
              return NULL;
          memcpy(resultado     , s1, l1); 
          memcpy(resultado + l1, s2, l2); 
      
          resultado[l1 + l2] = '\0';
          return resultado;
      }
      

      会更有效率,即使您检查NULL就像一个偏执狂,它会比strcpy()strcat()更快,因为您只会计算一次长度。

答案 1 :(得分:2)

您没有分配内存来保存termianting null。请记住,strlen()在计算字符串长度时不计算空终止符。但是,您需要在目标缓冲区中使用该空格来放置空终止符。

你应该写

 char *resultado =  malloc(tam + 1) ;

此外,

 resultado[tam+1] = '\0';

是非常错误的,因为,基于C的数组索引是0,在这里,你超过了分配的内存(是的,即使在分配tam+1的大小时也是如此)调用undefined behaviour。你根本不需要它,你可以摆脱它。

之后,作为旁注,正如Iharob所提到的那样,

  1. 在使用返回的指针之前检查malloc()是否成功。
  2. 在C标准中,sizeof(char)保证为1。在计算malloc()的大小时无需使用它。

答案 2 :(得分:0)

您应该分配比结果字符串长度多一个字节:

char *resultado =  malloc(tam + 1) ;

函数strcpystrcat会关注终止NUL,您无需手动添加它。