【问题标题】:C - How to concatenate Strings without string.h and with dynamic memory allocationC - 如何在没有 string.h 和动态内存分配的情况下连接字符串
【发布时间】:2019-06-07 19:37:12
【问题描述】:

我必须做一个练习,我有这个结构:

typedef struct {
    char *str;
    unsigned int len;
} String;

我的任务是编写一个字符串 Concat,它将 "Kartoffel""puffer" 连接到 "Kartoffelpuffer"(土豆饼)。

String concat(String l, String r)

字符串lr 在运行函数后不应更改。 首先,我在 main 中创建了两个字符串:

String1 *l = malloc(sizeof(String1));
String1 *r = malloc(sizeof(String1));
(*l).str = malloc(sizeof("Kartoffel"));
(*r).str = malloc(sizeof("puffer"));
(*l).str = "Kartoffel";
(*r).str = "puffer";
(*l).len = 9;
(*r).len = 6;

然后我写了concat函数:

String1 concat(String1 l, String1 r) {
    unsigned int i = 0;
    String1 *newStr = malloc(sizeof(String1));
    /* +1 for '\0' at the end */
    newStr->str = malloc(l.len + r.len + 1);
    newStr->str = l.str;
    /* The following line is not working */
    newStr->str[l.len] = *r.str;
    newStr->len = l.len + r.len;
    return *newStr;
}

我试图做的是使用指针算术。 当有一个指针指向像char *str这样的存储区域的开头时,应该可以用a[b]*((a) + (b))移动指针对吧?当我运行代码时,我得到分段错误(我希望它是正确的翻译。原文:"Speicherzugriffsfehler")。 如果有人能给我一个提示,我将不胜感激。 PS:对不起我的英语。

【问题讨论】:

  • 所以我还需要写一个从一个存储区复制到另一个存储区的函数?
  • return *newStr; 也会泄漏内存。

标签: c string pointers malloc concat


【解决方案1】:

首先,(*l).str = "Kartoffel"; 使(*l).str 指向"Kartoffel" 字符串字面量,这意味着分配给(*l).strmalloc() 的原始内存丢失了。 (*r).str = "puffer"; 也一样。为了避免这种情况,您可以做的一件事是通过在 for 循环中循环字符来将字符串复制到分配的缓冲区中(因为您不能使用 string.h)。

然后,在你的concat() 函数中,你做同样的事情。您使用malloc()newStr->str 分配内存(正确地为空终止符分配一个额外的char),但在下一行您重新分配该指针以指向l.str,它仍然指向字符串文字。然后,使用 newStr->str[l.len] = *r.str; 尝试修改字符串文字,这在 C 中是未定义的行为。

解决此问题的方法可能是再次将两个字符串复制到使用newStr->str = malloc(l.len+r.len+1); 分配的缓冲区中。

【讨论】:

    【解决方案2】:

    将内存分配给newStrnewStr->str
    可以使用两个指针。 char *to, *from;
    使用to = newStr->str;from = l.str; 设置指针
    *to = *from;复制字符
    使用 to++;from++; 推进指针
    重复直到*from == 0
    from 设置为from = r.str;
    to 不需要重置,因为它正确定位在newStr->str 的末尾。
    重复字符的副本。
    重复推进指针。
    *to = 0;设置一个终止0

    【讨论】:

      【解决方案3】:

      非常感谢您的帮助! 正如你们所说,我写了另一种方法来复制字符串。

      char * copyStr (char * dest,char * src){
          unsigned int index;
          for (index = 0; src[index] != '\0'; index++) {
                  dest[index] = src[index];
          }
          dest[index] = '\0';
          return dest;
      }
      

      我这样编辑了我的 concat:

      String1 concat (String1 l, String1 r){
          String1 *newStr = malloc(sizeof(String1));
          newStr->str = malloc(l.len+r.len+1);
          copyStr(newStr->str,l.str);
          copyStr((newStr->str+l.len),r.str);
          newStr->len = l.len+r.len;
          return *newStr;
      }
      

      newStr->str+l.len 将移动指针。如果 l.len 为 9,则指针将指向第 10 个字节,即第一个字符串 l 的结尾。所以字符串 r 将被复制到第一个字符串 l 后面的内存存储中。

      【讨论】:

      • 看起来不错,除了return *newStr; 泄漏内存:newStr 被复制到返回的对象,但随后有关原始指针的信息丢失了。最好返回一个String1*,这样您就可以在完成后释放该对象。
      猜你喜欢
      • 2021-06-11
      • 1970-01-01
      • 2013-03-01
      • 2021-02-09
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-02
      相关资源
      最近更新 更多