【问题标题】:String Implementation of a strcpystrcpy 的字符串实现
【发布时间】:2021-03-28 14:17:39
【问题描述】:

我应该在不使用库的情况下实现 strcpy 函数。我已经为此编写了代码,但似乎有一个错误(可能是内存泄漏,但我不确定)

但是,如果你们中的任何人都可以提供提示,是否是内存泄漏以及如何修复它,这将非常有帮助。

头文件:

实现文件:

    #include "string.h"
    #include <string.h>
    #include <stdlib.h>

    void copy (string *s1, string s2) {
      free((*s1));
      char *temp = malloc(strlen(s2 ->s) + 1);

      if(s2 -> s != NULL) {
      int i = 0;
      while(s2 -> s[i] != '\0') {
          temp[i] = s2 -> s[i];
          i++;
      }
      temp[i] = '\0';
      (*s1) -> s = temp;
      free(temp);
     }
    }

据我所知,设置字符串效果很好,复制功能似乎有问题。

【问题讨论】:

  • @MatheusRossiSaciotto 字符串是可怕的 typedefd 指针。
  • 如果你免费 free(temp); (*s1) -&gt; s 也发布了
  • Set 中的(*s1) -&gt; s = s; 无效,您使用的是引用,对象依赖于 char 数组
  • temp 和 (*s1) -&gt; s 指向同一个内存,如果你释放这块内存,你就会毁掉这两个内存。当你使用 free 时,你正在释放内存,指针只是变量,就像一个 int。
  • 你有一个指针副本,正在删除内存。

标签: c string malloc strcpy


【解决方案1】:

一个启动点是这样的:

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

typedef struct {
    int len;
    char *s;
} string_t;

typedef string_t *string;

void set(string *s1, char *s);
void copy(string * s1, string s2);
void concat(string *s1, string s2);
void print(string s2);


void dispose(string s) {
    if (s != NULL) {
        if (s->s != NULL) free(s->s);
        free(s);
    }
}

void set (string *s1, char *s) {
    if (*s1 != NULL) dispose(*s1);
    *s1 = malloc(sizeof(**s1));
    (*s1)->len = strlen(s);
    (*s1)->s = malloc((*s1)->len + 1);
    char *temp = (*s1)->s;
    while ((*temp = *s) != '\0') {
        s++;
        temp++;
    }
}

void copy (string *s1, string s2) {
    set(s1, s2->s);
}


int main()
{
    string s = NULL;
    set(&s, "teste");
    printf("%s\n", s->s);
    dispose(s);
}

我认为不允许使用strlen。

【讨论】:

  • 旁白:(*s1)-&gt;s != NULL 不需要测试
  • 我推荐 dispose(*s1); 在 set() while 循环之后。
【解决方案2】:

您的代码中存在许多问题,具体取决于您的使用方式,例如

copy 创建字符串的副本只是为了在之后立即销毁 (free)。这显然不是故意的。

copy frees 无论s1 指向什么。这仅在之前已malloced 时才有效。有吗?

print 在打印后销毁 (free) 字符串。这是故意的吗?

set 将指向参数s 的指针存储在s1 中。一旦s 的生命周期结束,这将使s1 无效。 (马修斯·罗西·萨西奥蒂)

您的问题没有指出这些功能的用途和使用方式。但目前,print 和 copy 几乎没有用处。

一般来说,一个库应该要么完全自己进行内存管理(malloc、free ...),要么完全由调用者处理。

【讨论】:

  • 打印末尾的 free 是有意的,它应该释放我们分配给字符串的任何内存。 ** set(&s1, "Hallo); ** print(s1); 这就是我尝试测试函数的方式。
  • 明智吗?这意味着您不能将 prints 添加为 -- 例如-- 调试。
【解决方案3】:

现在设置和打印出来似乎工作正常。但是我仍然对不知道我是否有内存泄漏感到不舒服:

复制功能:

    void copy (string *s1, string s2) {
      //free((*s1));

      char *temp = malloc(strlen(s2 ->s) + 1);
      *s1 = malloc(strlen(temp));

      if(s2 -> s != NULL) {
        int i = 0;
        while(s2 -> s[i] != '\0') {
            temp[i] = s2 -> s[i];
            i++;
        }
      temp[i] = '\0';
      (*s1) -> s = temp;
      free(temp);
     }
  }

打印功能:

    void print(string s1) {
      if(s1 != NULL) {
      int i = 0;
      while (i < strlen(s1 -> s)) {
        printf("%c", s1 -> s[i]);
        i++;
      }
    } else {
    return;
   }

  }

对缩进感到抱歉。

【讨论】:

  • strlen(temp); 是 char *temp = malloc(strlen(s2 -&gt;s) + 1); 之后的 UB。 temp 指向的内存指针是不确定的。
  • malloc(strlen(temp)); 空间不足,减 1,用于保存 字符串。 (*s1) -&gt; s = temp; free(temp); 是错误的,正如其他 cmets 所指出的那样。
  • @chux-ReinstateMonica 但如果我要将 temp 中的任何内容复制到 s1,我需要分配足够的内存:(*s1) = malloc (sizeof(strlen(temp))
  • 应该是(*s1) = malloc (strlen(temp) + 1)。
猜你喜欢
  • 2011-07-04
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 2011-04-23
  • 2021-07-19
  • 2013-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多