如何为typedef'd结构正确分配内存

时间:2014-06-04 20:39:34

标签: c pointers memory-management struct malloc

以下代码根据哪一点更改其输出,点1或点2是分配的一些数据。在数据分配之后执行调用pthread_cond_init(&(c->cond1), NULL);似乎会覆盖其他内存。

 #include <stdio.h>
 #include <stdlib.h>
 #include <pthread.h>

 typedef struct {
   int nmax, n;
 } Data;

 Data* newData(int nmax) {
   Data *data= (Data*) malloc(sizeof(Data*));
   data->nmax= nmax;
   data->n= 0;
   return data;
 }

 void checkData(Data* data) {  
     if (data->n != 0) {
        fprintf(stderr, "Data changed %i \n", data->n);
        exit(1);
   }
 }

 typedef struct {
     Data* data;
     pthread_cond_t cond1, cond2;
 } *Test;

 Test nuevaCasilla() {
     Test c = (Test) malloc(sizeof(Test*));
     // Point 1 FAILS
     //c->data = newData(100);
     pthread_cond_init(&(c->cond1), NULL);
     pthread_cond_init(&(c->cond2), NULL);
     // Point 2 SUCCESS
     c->data = newData(100);
     return c;
 }

 int main(int argc, char** argv) { 
     Test c = nuevaCasilla();
     checkData(c->data);
     return (EXIT_SUCCESS);
 }

如果在点1中进行了呼叫c->data = newData(100),则输出为

Data changed -2147483648 
logout

如果在第2点进行了呼叫c->data = newData(100),则输出为

logout

修改

即使更改了测试结构,@ nos指示错误仍然出现。

typedef struct {
    Data* data;
    pthread_cond_t cond1, cond2;
} Test;

Test* nuevaCasilla() {
    Test* c = (Test*) malloc(sizeof(Test*));
    // Point 1 FAILS
    c->data = newData(100);
    pthread_cond_init(&(c->cond1), NULL);
    pthread_cond_init(&(c->cond2), NULL);
    // Point 2 SUCCESS
    //c->data = newData(100);
    return c;
}

int main(int argc, char** argv) { 
    Test* c = nuevaCasilla();
    checkData(c->data);
    return (EXIT_SUCCESS);
}

EDIT2

对于Test不是typedef&lt; struct的代码,对内存的调用应该是

Test* c = (Test*) malloc(sizeof(Test));

请注意malloc中没有星号。

1 个答案:

答案 0 :(得分:3)

这一行:

Test c = (Test) malloc(sizeof(Test*));

应该是:

Test c = (Test) malloc(sizeof(*c));

因为您已经创建了无标记结构并且键入了它的指针类型:

typedef struct { ... } *Test;

你不能使用Test *(这意味着指向结构类型的指针),但你也不能使用*Test。事实上,我认为sizeof(*c)是获得结构大小的唯一方法。通常,避免创建作为指向结构的指针的typedef名称。使用:

typedef struct SomeTag { ... } SomeTag;

然后使用SomeTag *等。

因为您只为指针(指向结构的指针)分配了足够的空间,所以您没有分配足够的空间,因此当您走出该空间时会遇到问题。

使用valgrind会向您显示您的错误。