【问题标题】:C++ segmentation fault on allocation分配时的 C++ 分段错误
【发布时间】:2014-09-17 11:19:54
【问题描述】:

好吧,在此之前我搜索了很多关于“导致分段错误的原因”,但我没有找到任何关于我的情况的信息。

事情是这样的:

DNA_INIT Creation::InitalizeUserActivity()
{
  SUData *curr = new SUData[__USERCOUNT];
  readSQL(curr,__USERCOUNT);
  // return something
}

我在 dna.h 中有这个函数,这是它的文件,名为 dna.cpp

SUData *readSQL(SUData *tmp,int size)
{
  ifstream getSQL;
  getSQL.open("../noSQL/StoredUserDataNoSQL.inc");

  int count;
  string tmpstr;

  ifstream focus;
  focus.open("../instruction.bin",ios::app);
  focus >> tmpstr >> count;
  focus.close();

  int c = 0;
  tmp = new SUData[size];

  while(getSQL >> tmp[c].id >> tmp[c].access >> tmp[c].u_name >> 
    tmp[c].u_surname >> tmp[c].u_username >> tmp[c].u_password 
    >> tmp[c].u_email )
    {
      c++;
    }

  return tmp;
}

当我尝试执行时,它给了我分段错误。我试过了,但还是一样。感谢您的建议。

编辑:我删除了 tmp = new SUData[size];但还是一样

【问题讨论】:

  • __USERCOUNT 有多大?你确定够了吗?您的问题是“关于分配” - 哪一行导致了问题?
  • 为什么要在 append 模式下打开 input 流?另外,按照它的名字(../instruction.bin),它是一个二进制文件,所以也许你应该以二进制模式打开它?
  • 至于你的问题,每当你的程序崩溃时,你应该在调试器中运行它的调试版本。调试器将在崩溃的位置停止,还可以让您检查并向上走函数调用堆栈,还可以让您检查变量的值。请在调试器中运行您的程序,并告诉我们它在哪里崩溃了。
  • 还有一件事要考虑,如果../noSQL/StoredUserDataNoSQL.inc 文件中的数据多于变量size 所指示的数据怎么办?然后,您将在为tmp 分配的内存之外写入,这导致undefined behavior。你可能应该有例如while (c < size && getSQL >> ...)
  • @doctorlove 它只有 4 个

标签: c++ memory-management allocation


【解决方案1】:

啊,现在我看到了问题:您在InitalizeUserActivity 中分配了一个指针,然后将它传递给readSQL再次分配(导致内存泄漏)。

更大的问题是,作为所有参数,指针按值传递,即readSQL 函数仅对来自的指针的副本进行操作InitalizeUserActivity。在readSQL 函数内更改指针时,仅更改副本。这当然会导致您将无法从readSQL 函数外部访问的数据读入内存。

有一个非常简单的方法可以解决这个问题,那就是不要在readSQL 函数中分配任何新的东西(因为它已经分配了)。

【讨论】:

  • 解释清楚,那么如何解决这个问题,我的意思是我想在 readSQL 函数中更改 curr 怎么做。
  • @SashaValentine 只是不要在 readSQL 函数内再次分配。那么就没有内存泄漏(前提是你释放了InitalizeUserActivity中分配的内存),数据被读入了InitalizeUserActivity函数中分配的内存中。
  • @Sasha 要么您不将分配的数据传递给函数并在内部分配并返回函数中分配的内存;或者您遵循 Joachim 的建议:您将分配的内存传递给函数,不要在内部重新分配(而且,我可能会补充一点,不要返回任何东西——为什么?tmp 的值是在函数外部设置的并且没有更改)。跨度>
【解决方案2】:

首先为curr分配一个空间并将其发送到函数readSql,然后再次为tmp变量分配另一个空间; tmp将分配的地址保存在curr,错了不需要重新分配。

【讨论】:

  • 当我删除 tmp = new SUData[size];它不会改变仍然相同的情况
  • 没关系,它的错误实现,你不能调试你的代码?
  • 由于重复分配,我不希望该程序在那里兑现。 (当然,当它尝试使用读取到调用者current 的假定信息时,它可能会在以后崩溃。)
  • 为什么你认为 c 没有超过你的尺寸?
  • 变量c,你确定你文件中的行号不大于__USERCOUNT
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多