在C中,如何释放全局静态指针?

时间:2014-02-04 12:37:17

标签: c pointers static free

在C中,请查看此代码,

static char* test = NULL;
typedef struct
{
    char* member1;
}TestStruct;


void testCode()
{
    TestStruct ts;
    test = malloc(10*sizeof(char));
    //assign characters to each test 0 ~ 9 positions 
    ts.member1 = test;
    // using ts, then can I free static pointer test using free()?
    free(test);
}

1)这个免费代码是对的吗? 2)分配的内存测试指向在堆中,对吗? 3)测试是在.bss?
4)如果testCode()函数可以在线程中调用,测试就是一个,对吗?但每次线程调用testCode()时,测试都会被赋予新指针并使内存泄漏,对吗?那么,我可以使用此代码来避免它吗?

 Mutex_Start
 if(test == NULL)
     test = malloc(10*sizeof(char));
 Mutex_End

请帮帮我。

4 个答案:

答案 0 :(得分:5)

  

这个免费代码是对的吗?

如果意图是分配10个字节的内存,那么指定指向该内存的指针,然后删除内存,那么它是正确的。

但是代码中的评论表明你有点困惑。 ts.member1 = test;只会使另一个指针指向同一块数据。你没有复制任何东西。从您free(test)开始,testts.member1都指向无效的内存。

  

分配的内存测试指向在堆中,对吗?

  

测试是在.bss?

  

如果可以在线程中调用testCode()函数,test是1,对吗?

每次调用该函数时,都会创建一个新的内存块。但同样的功能也free()内存。当然,如果另一个线程在第一个线程到达free()之前获得焦点,它将分配另一块内存。例如:

  • 线程1:地址1234的malloc内存
  • 测试指向1234
  • 上下文切换
  • 线程2:地址为5678的malloc内存
  • 测试指向5678
  • 没有任何东西指向1234 - 内存泄漏
  • 线程2:地址为5678的空闲内存。注意:free()不会将指针设置为NULL。
  • 主题2:完成
  • 线程1:地址为5678的空闲内存(测试仍然指向那里)
  • 线程1:崩溃&烧

所以你有内存泄漏和运行时崩溃。

  

那么,我可以使用此代码来避免它吗?

对NULL的检查可防止第二个线程分配任何新内存。如果这是意图并且两个线程都应该访问相同的内存,那么它将防止上述错误。但实际内存也必须受到竞争条件的保护,代码变得复杂。执行此操作的正确方法可能是在本地分配所有内容,而不是通过文件范围指针。

答案 1 :(得分:3)

我想你错过的是

test = NULL; 

之后

free(test);

并在免费提供同样的保护,就像在mallocing之前做的那样

答案 2 :(得分:1)

在所有线程完成之后,您可以随时在free注册的函数中调用atexit,以便在进程结束时运行。但这确实是一个小问题,因为无论如何,这个过程将最终释放所有分配的内存。

更重要的是创业公司。 Modern C,AKA C11,有线程和互斥,所以你可以使用它,但它还有另一个更合适的构造,这里是原子。

static char*_Atomic test = ATOMIC_VAR_INIT(0);


void testCode(void)
{
    TestStruct ts;
    while (!test) {
      char* tmp = malloc(10*sizeof(char));
      if (!atomic_compare_exchange(&test, tmp, 0))
        free(tmp);
    }
   /* Do whatever you have to do, here */
   ...
}

如果您的平台不支持C11的这个方面,您可以通过P99在许多平台上模拟它。

答案 3 :(得分:0)

如果您希望多个线程在同一个内存上工作,您应该将malloc和free放入启动并加入线程的代码中。你也可以做一些引用计数:

static char* test = NULL;
static int refCount = 0;

void testCode()
{
    TestStruct ts;

    {
        //mutex lock;
        if (!refCount++)
            test = malloc(10*sizeof(char));
    }

    //assign characters to each test 0 ~ 9 positions 
    ts.member1 = test;

    {
        //mutex lock;
        if (!--refCount)
            free(test);
    }
}

如果全局指针是某种全局资源,并且线程不必并行处理它,那么你应该在整个函数周围放置一个互斥体,从malloc到free。如果你只保护malloc并单独释放,一个线程可以释放另一个线程正在处理的内存!