【问题标题】:String-copying function results in `pointer being freed was not allocated`字符串复制函数导致“未分配指针”
【发布时间】:2016-10-25 20:49:45
【问题描述】:

我有以下功能:

void stringcopy(char * to, char const * const from)
{
    int size = 1;
    while (from[size] != '\0') { ++size; }

    if (to != 0) { delete [] to; }
    to = new char[size];

    for (int i = 0; i < size; i++) { to[i] = from[i]; }
}

顾名思义,它使用动态分配复制一个字符串。


我认为我使用它的方式并不重要(因为我正在努力使这个函数变得健壮),但这里有一些例子:

CD::CD(char * s1, char * s2, int n, double x)
{
    stringcopy(performers, s1);
    stringcopy(label, s2);
    selections = n;
    playtime = x;
}

CD::CD(const CD & d)
{
    stringcopy(performers, d.performers);
    stringcopy(label, d.label);
    selections = d.selections;
    playtime = d.playtime;
}

等等


不幸的是,我在使用该函数时收到以下错误消息:pointer being freed was not allocated

我认为它发生在if (to != 0) { delete [] to; }


为什么这条线不能防止释放未分配的内存?

【问题讨论】:

  • tostringcopy() 的本地。为了使调用者的(指针)值能够被修改,您必须通过引用传递它或传递一个指向它的指针。
  • @JohnBollinger -- 我不是在使用char *吗?或者,我必须使用双指针吗?
  • 您正在通过值传递char *stringcopy() 可以使用它的该指针值的副本来修改它指向的char(如果有),但它不能修改调用者的指针副本,这是您需要做的。所以正如我所说,你需要通过引用传递指针,或者传递一个指向它的指针(即char **)。
  • 完全实现字符串有点棘手,而且(更重要的是)几乎是一个已解决的问题。您是否有充分的理由自己而不是使用 std::string
  • 同时练习 C++可以 没问题。但是,如果你决定重新发明眼前的每一个轮子,就很难取得很大进展,因为当许多部分至少部分损坏时,很难专注于代码的一部分(而且你永远不确定哪个部分确实有效,而哪些无效)。此外,如果您要重新发明一个轮子,最好至少对现有轮子的外观有所了解,这样您的轮子至少接近圆形。

标签: c++ string memory-management deep-copy


【解决方案1】:

你在这里做什么

if (to != 0) { delete [] to; }
to = new char[size];

正在释放本地to 变量指向的内存,重新分配它并将字符串存储在那里。

这个新的本地内存地址(我们称之为to1)从不暴露给外界,因为它不是从函数返回的。函数 get 是to 地址的副本。为了解决这个问题,您需要将 to 设为双指针。或对指针的引用。

【讨论】:

  • 那么,除了将定义改成char * &amp; to之外,我还要改什么?
  • 应该没问题
  • 我的编译器告诉我不然。 :)我要更改块内的任何内容吗?
  • 那要看函数的使用了。也许你正在向它传递一个未初始化的变量(例如表演者),它默认初始化为 0,所以在它上面调用了 delete?
  • 是的,它最初是未初始化的。这个函数兼作初始化器(因此to = new char[size];)为什么要在它上面调用delete?
猜你喜欢
  • 1970-01-01
  • 2019-12-04
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
  • 1970-01-01
相关资源
最近更新 更多