2012-04-02 100 views
3

这个错误总是被触发,当我试图释放我分配的结构第二次,它不应该,因为结构设置为NULL后,我解放它。错误:“指针被释放未被分配”在c

这里是我的结构与它里面没有真正的指针:

typedef struct{ 
     int frame; 
     double timestamp; 
     int identifier; 
     int state; 
     int unknown1; 
     int unknown2; 
     mtVector normalized; 
     float size; 
     int unknown3; 
     float angle; 
     float majorAxis; 
     float minorAxis; 
     mtVector unknown4; 
     int unknown5[2]; 
     float unknown6; 
    }Touch; 

准系统主要功能:

int main(){ 
    Touch *myTouch = NULL; 
    int inputCounter = 0; 
    //whenever a touch is recognized: 
    ... 
    myTouch = (Touch*)realloc(myTouch,sizeof(Touch)*(inputCounter++)); 
    ... 
    // everything works fine until: 
    freeTouch(myTouch); 
} 

void freeTouch(Touch *f){ 
    if(f != NULL){ 
     free(f); 
     f = NULL; 
    } 
} 

任何人有一个想法?

+0

该代码应该正常工作。你能写一个[最小的测试用例](http://sscce.org)吗? – 2012-04-02 10:46:40

+0

你可以展示“第二次”实际发生的情况吗?所示的代码只调用'freeTouch()'一次。 – unwind 2012-04-02 10:49:57

回答

3

f是一个局部变量。 free(f)将影响分配的内存,但f = NULLfreeTouch(myTouch);中的myTouch没有影响。

尝试

void freeTouch(Touch **f){ 
    if(*f != NULL){ 
     free(*f); 
     *f = NULL; 
    } 
} 

来代替,而freeTouch(&myTouch)

+1

这不太可能是问题,因为包含的代码不会显示多次调用'freeTouch()'。另外,'free(NULL)'没问题,所以没有必要保护它。 – unwind 2012-04-02 10:49:32

+0

在我原来的代码myTouch和inputCounter是全局的,但你的提示我修好了! (myTouch!= NULL){ free(myTouch); myTouch = NULL; } } – 2012-04-02 10:53:09

+1

@unwind:我猜OP在他的'...'的某个地方有多次对'freeTouch'的调用。主要的问题是他没有在这种情况下设置myTouch = NULL。 – Zeta 2012-04-02 10:55:02

1

首先,切勿使用

x = realloc(x, size); 

,因为如果x之前分配和realloc失败了,你让它NULL而内存仍然存在,因此,您创建的垃圾。

其次,

void freeTouch(Touch *f); 

得到由值的指针,因此不能改变指针本身。所以你的f = NULL;是无效的。您需要将代码更改为:

int main(){ 
    Touch *myTouch = NULL, temp; 
    int inputCounter = 0; 
    //whenever a touch is recognized: 
    ... 
    temp = realloc(myTouch,sizeof(*temp) * (inputCounter++)); 
    if (temp == NULL) 
     /* handle error */ 
    myTouch = temp; 
    ... 
    // everything works fine until: 
    freeTouch(&myTouch); 
} 

void freeTouch(Touch **f){ 
    if(f != NULL && *f != NULL){ 
     free(*f); 
     *f = NULL; 
    } 
} 

旁注:这是一个好主意,用realloc(同样地malloc)是这样的:

x = realloc(count * sizeof(*x)); 

没有必要投下输出或realloc。此外,sizeof(*x)允许您不要每次重复x的类型。

+2

顺便说一句,没有必要检查'* f!= NULL',因为'free(NULL)'是明确定义的。 – 2012-04-02 10:50:06

+0

@OliCharlesworth,你说得对,但这只是我的习惯 – Shahbaz 2012-04-02 11:01:10

2

你有两个问题。首先,从mallocrealloc明确投出返回值并不是一个好主意。如果您忘记包含原型/标题,则会导致问题。

其次,释放f内部功能释放本地拷贝。在C获得参考之前,有两种可能性。首先一个指针传递到指针和使用:

void freeTouch (Touch **pF){ 
    if (*pF != NULL){ 
     free (*pF); 
     *pF = NULL; 
    } 
} 
: 
freeTouch (&myTouch); 

或传回空,因此你可以分配:

void *freeTouch (Touch *f){ 
    free (f); 
    return NULL; 
} 
: 
myTouch = freeTouch (myTouch); 

您会发现,第二个不关心你是否在传递NULL - 尝试释放NULL指针是完全可以接受的,因为它实际上是一个无操作(除了函数调用本身)。

相关问题