代码之家  ›  专栏  ›  技术社区  ›  James

作用域、数组和堆

  •  0
  • James  · 技术社区  · 6 年前

    所以,我有这个数组。它需要在这个函数的范围之外访问。我一直在把一个指向它的指针打成一对,然后打成一个哑巴。但一旦我超出了范围,本地堆栈就不存在了,数组无效,我只是得到了一个无用的指针,对吗?

    所以我尝试将这个数组放到作用域转换堆中,它将一直保留到稍后删除它为止。但我在工作中遇到了一些问题。现在,G++正在咳嗽关于从“int”到“int*的无效转换的错误。

    void randomFunction(int x, int y, int width, int height)
    {
      int **blah[4] = {x, y, width, height};
      std::pair <foobar*, int* > tempPair (foobar1, blah);
      randomDeque.push_front(tempPair);
    }
    

    我也试过这样初始化它:

    int *blah[4] = new int[4];
    

    …它指出数组必须用括号括起来的初始值设定项初始化。

    我真的不习惯使用指针。我做错什么了?

    4 回复  |  直到 15 年前
        1
  •  1
  •   Drakosha    15 年前

    我觉得整个概念很奇怪。如果在堆栈上声明数组,则它将不存在于函数范围之外。如果您使用“新建”来分配它,请确保您有时间“删除”它,否则它是 内存泄漏 ! “new”的正确代码是:

    int *blah = new int[4];
    ...
    // don't forget to:
    delete [] blah;
    
        2
  •  2
  •   David Joyner    15 年前

    有两个问题。首先,您确实对指针/数组感到困惑:

    int a[4]; // this is an array of 4 integers, a is the name of the array
    int *a[4]; // This is an array of 4 *pointers* to int
    

    所以你的声明:

    int **blah[4];
    

    定义指向指针数组的4个指针的数组。也许你对以下事实感到困惑(我知道我学C的时候)。如果你 声明 变量:

    int *a;
    

    这是指向整数的指针的声明。但是,如果您有一个变量a,它是一个指针,那么您可以使用*a得到它指向的对象(这里是一个整数):

    *a = 1; // a is a pointer (i.e. an address), *a is the value pointed to by a.
    

    所以*in声明用于声明指针,而*in语句用于尊重值。

    但第二个问题本身与指针无关。它是关于资源管理(内存是一个,而文件是一个,锁是另一个)。堆栈上分配的任何内容在超出作用域时都不再存在。在纯C中,实际上只有一个解决方案:使用malloc在堆上分配,并确保随后释放。所以你应该做如下的事情:

    // foo is a struct
    foo *init_foo()
    {
        foo* tmp;
        tmp = malloc(sizeof(*tmp));
        // initialize tmp
    
        return tmp;
    }
    

    然后,您将使用另一个功能来清理它:

    foo *a;
    a = init_foo();
    // do stuff
    clean_foo(a);
    

    示例:文件*handle和fopen/fclose(除了分配内容,还有一些与操作系统相关的内容来处理该文件)。另一种解决方案是使用alloca,它不是标准的C,但是被许多工具链支持。

    在C++中,可以使用智能指针,例如使用引用计数来进行资源管理。我对C++不太熟悉,我相信人们会对这一部分有所兴趣。使用引用计数的想法是,它仍然提供了自动指针的一些优点(您不必自己调用delete,这对于非琐碎的项目极易出错),但不需要纯粹基于范围。一个基于引用计数的智能指针在Boost中共享。

        3
  •  1
  •   quant_dev    15 年前

    我不确定我是否正确地得到了你想要做的,但是如果你想返回一个对int数组的引用,它将在 randomFunction 返回,一个很好的方法是使用boost:

    #include <boost/shared_ptr.hpp>
    #include <vector>
    
    boost::shared_ptr<std::vector<int> > randomFunction(int x, int y, int width, int height)
    {
      boost::shared_ptr<std::vector<int> > blahPtr(new std::vector<int>(4));
      (*blahPtr)[0] = x;
      (*blahPtr)[1] = y;
      (*blahPtr)[2] = width;
      (*blahPtr)[3] = height;
      return blahPtr;
    }
    

    你不必记住 delete 惯性导航与制导 blahPtr --当它的所有副本都超出范围时,Boost将删除 std::vector 对象,C++标准库将删除基础数组。

        4
  •  0
  •   badgerr    15 年前

    看起来您需要一个4x4数组,在这种情况下,您应该像这样创建它(我头上没有测试过的代码):

    int **blah = new int* [4];
    for(int i = 0; i < 4; ++i)
    {
        *blah[i] = new int[4];
    }
    

    或者,您可以创建一个一维数组,并将其视为二维数组:

    int *blah = new int[16];
    #define ELEM(x,y) w*4+h
    blah[ELEM(1,1)] = 123;