【问题标题】:Need dynamically allocated (initialized) static variable需要动态分配(初始化)的静态变量
【发布时间】:2011-02-25 16:11:20
【问题描述】:

我需要一个 C 中的静态字符串(等效)变量,但我在实现类似的东西时遇到了麻烦。

每次调用该函数时,我都需要向该字符串添加内容。我试过了

static char *result = (char*)calloc(0, sizeof(char));

但是这样我得到了:

错误:初始化元素不是 常数

这是有道理的,但我真的不知道如何以不同的方式执行此操作(也尝试使用全局变量,但没有成功)。

有人可以帮忙吗?

【问题讨论】:

    标签: c variables static memory-management


    【解决方案1】:

    静态初始化器必须是常量,如您的错误消息所示。

    分配它NULL,然后在其他一些函数中,测试它是否为NULL,分配它需要的资源(一些合理的默认值)并从那里开始。确保您在完成后进行清理,如果这是一个线程环境,我建议您采用不同的方式将它放在您需要的任何地方传递的其他存储中。

    【讨论】:

      【解决方案2】:

      如果您需要增加数组长度,请改用 realloc。

      
      char *buf = NULL;
      
      while(/* some loop here */){
          buf = realloc(buf, sizeof(/* new content */));
          ... // copy your new content to buf here
      }
      

      如果你只添加内容,最好使用列表来代替?

      【讨论】:

      • @S.J 我非常明确地说,您的代码假定 realloc 就地发生。但是 realloc 可能会重新定位数据,在这种情况下,buf 将包含无效地址,访问它可能会使程序崩溃。修复你的代码,我会删除我的反对票。
      • @S.J.谢谢。最好也添加if( !buf ) ... // out of memory
      • 更好的是重新分配到一个临时变量,测试该变量并在正常情况下分配回:tmp = realloc(buf, newsize); if (tmp) buf = tmp; else /* error; but `buf` still points to valid memory */;
      【解决方案3】:

      我见过的最常见的方法是初始化一个指向 NULL 的指针,并存储一个长度 - 可选地,还存储一个结束指针。调用该函数时,检查缓冲区中是否有足够的可用空间,如果没有,则重新分配内存块。通常你不想每次都重新分配,而是增加一些固定的数量(通常根据系统的内存对齐方式选择),或者将之前的大小增加一倍(确保你实际上有足够的空闲空间!)。

      #define MYDATA_GROW_AMOUNT (12345) //exploit memory alignment on your system
      ...
      /* if the compiler supports it, consider using __thread__ here */
      static /* __thread__ */ char  *mydata     = NULL;
      static /* __thread__ */ char  *mydata_end = NULL;
      static /* __thread__ */ size_t mydata_len = 0;
      ...
      /* gcc? you might want to use
             if(__builtin_expect((mydata_len < required_data_len),0))
         here instead */
      if(mydata_len < required_data_len)
      {
          mydata_end = mydata + mydata_len;
          mydata_len += MYDATA_GROW_AMOUNT;
          mydata = realloc(mydata,mydata_len);
      }
      ...
      

      【讨论】:

        【解决方案4】:

        我能够让它适用于“固定”大小的数组,即长度可以在运行时定义,而不是编译时。我创建了一个函数,它本身具有空指针A 作为输入,然后在其中更改它并返回它。长度len 是自定义运行时长度:

        char *malloc_char_array(char* &A, int len);
        

        然后在数组初始化中调用那个函数:

        static char *result = malloc_char_array(result, 50); //test length of 50
        

        静态初始化只在第一次调用函数时发生,因此它适用于需要动态大小的数组(即在编译时未定义),但在整个程序运行期间仍保持固定.

        分配函数看起来像:

        char *malloc_char_array(char* &A, int len)
        {
            A = (char*) malloc(len * sizeof(char));
            return A;
        }
        

        使用此方法无需释放“静态”分配的内存,只需让它留在堆栈中直到程序退出。

        【讨论】:

          猜你喜欢
          • 2017-11-10
          • 1970-01-01
          • 2011-08-22
          • 2010-12-22
          • 1970-01-01
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多