【问题标题】:C advice on excepting handlng关于异常处理的 C 建议
【发布时间】:2019-03-04 17:05:53
【问题描述】:

由于我对 C++ 还很陌生,因此在处理我的学校作业时遇到了麻烦。我以前从未接触过异常。

我需要为我的任务做的是创建一个异常机制来计算可以在程序中分配多少内存(以 MB 为单位)。

我应该使用new[] 运算符和catch() 并且仅限于使用一个变量。

我已经尝试了这些代码,这就是我目前所拥有的。我不知道我是否走在正确的轨道上。任何建议表示赞赏。谢谢。

int main() {

  char *mem;

  unsigned long long count = 1;

  while (1) {
    mem = new char[1025 * 1054];
    if (mem == NULL)
      break;

    free(mem);
    count++;
  }

  std::cout << "count: " << count * 1024000;
}

【问题讨论】:

  • 这不一定与异常有关,但您应该始终free() 你是什么malloc()delete 你是什么newdelete[] 你是什么new[]。任何其他混合都是不好的。
  • @alterigel 哦,我明白了。谢谢!这种情况下如何实现 catch?
  • This 可能对你有用。

标签: c error-handling


【解决方案1】:

警告 free 无效且具有未指定的行为,删除分配内存的方法是delete [] mem;

除此之外,在循环中执行 new 然后 delete 是没有用的,如果你想检查你不需要删除的限制分配大小(也不是免费当然)

如果您想知道 continuous 块的最大大小,请执行初始 malloc ,然后 realloc 在循环中增加大小得到NULL

例如

#include <stdlib.h>
#include <iostream>

int main() {
  void * mem = malloc(0);
  size_t count = 0;

  while ((mem = realloc(mem, (++count)*1024*1024)) != NULL)
    ;

  free(mem);

  std::cout << "count: " << --count << "Mb" << std::endl;
}

请注意,程序不会写入分配的内存,所以我可以在我的树莓派上执行它而不会杀死它产生一个交换:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra a.cc 
pi@raspberrypi:/tmp $ ./a.out
count: 1023Mb
pi@raspberrypi:/tmp $ 

使用 C++

#include <stdlib.h>
#include <iostream>

int main() {
  char * mem;
  size_t count = 0;

  try {
    while (true) {
      mem = new char [(++count)*1024*1024];
      delete [] mem;
    }
  }
  catch (std::bad_alloc &) {
  }

  std::cout << "count: " << --count << "Mb" << std::endl;
}

编译和执行:

pi@raspberrypi:/tmp $ g++ -pedantic -Wextra a.cc 
pi@raspberrypi:/tmp $ ./a.out
count: 543Mb

结果不一样,比较真实,对应我有的空闲内存

【讨论】:

  • 哦,我明白了。谢谢。在这种情况下如何实现 catch?
  • @coolo 也不例外,只是测试malloc / realloc 的结果不是NULL
  • 如何实现重新分配?不知道该怎么做。
  • @coolo reallocmalloc 是标准库的一部分,也在 C 中
  • 运行数据需要很长时间是正常的吧?
【解决方案2】:

void* operator new ( std::size_t count ); 将在分配内存失败时抛出异常 std::bad_alloc

您所要做的就是创建一个 allocate 函数,它会在失败时调用自己,并使用较小的内存大小;例如你可以做这样的事情:

#include <iostream>

void allocate_me(size_t size)
{
    try{
        uint64_t* a = new uint64_t[size] ;
        std::cout << "Size is : " << size << std::endl;
    }
    catch(std::bad_alloc &e)
    {
        allocate_me(size-1024);
    }
}

int main()
{
    size_t var = 1024*1024*1024;
    allocate_me(var);
    std::cout << "Hello, world!\n";
}

请注意,初始内存大小和减量取决于您的系统。

另一种解决方案可能是简单地查看可用 RAM - 在 Linux 中,您可以使用 sysinfo 或查看文件 /proc/meminfo - 并从该点开始。

【讨论】:

  • 嗨@Clonk,我可以知道 uint64_t 是什么意思吗?
  • 哦,好的非易失性存储器。谷歌搜索。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多