结构操作需要一些解释

时间:2014-12-28 20:23:13

标签: c pointers struct

我有以下代码:

//length, width, height
typedef struct {
float L, W, H;
} TDim;

//contains details for each geometrical form
typedef struct {
char *id; // each geometrical form has a unique id
float volume;
TDim *dim;
} TForm;

TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));

return F;
}

这是在更多结构中操纵变量和指针的一个很好的练习。

我想要做的是存储id(基本上是字母'F'后跟1,2,3 ...),长度,宽度和高度的某个矩形长方体以计算其体积。 / p>

我需要对-> vs .的使用情况进行一些解释 我了解-> 使用地址.使用会员。

int main()中,我有:

F[0].id = "F1"; //the first cuboid has the id "F1"
F[0].dim[0].L = 1; //the first cuboid has length = 11
//could have used F[0].dim->L = 1; as well?
F[0].dim[0].W = 2;
F[0].dim[0].H = 3;

F[1].id = "F2"; //the second cuboid has the id "F2"
F[1].dim[1].L = 4; //this is where it breaks down - SEG_FAULT (I've used gdb to catch it)

导致该行中的SEG_FAULT的原因是什么?

1 个答案:

答案 0 :(得分:2)

在此功能中:

TForm* FormAlloc()
{
TForm *F = (TForm*) malloc(MAX * sizeof(TForm));
F->id = (char*) malloc(MAX * sizeof(char));
F->dim = (TDim*) malloc(MAX * sizeof(TDim));

return F;
}

您创建MAXTForm元素的动态数组,但之后只为第一个iddim成员分配内存,因此会出现段错误你试图在第二个元素中存储内存。

你需要这样的东西:

TForm* FormAlloc(void)
{
    TForm *F = malloc(MAX * sizeof(TForm));

    if ( !F ) {
        perror("couldn't allocate memory");
        exit(EXIT_FAILURE);
    }

    for ( size_t i = 0; i < MAX; ++i ) {
        if ( (F[i].id = malloc(MAX)) == NULL ) {
            perror("couldn't allocate memory");
            exit(EXIT_FAILURE);
        }

        if ( (F[i].dim = malloc(MAX * sizeof(TDim))) == NULL ) {
            perror("couldn't allocate memory");
            exit(EXIT_FAILURE);
        }
    }

    return F;
}

最有可能的情况是,您不希望将MAX用于所有这三个目的,也就是说,您需要与TForm完全相同数量的元素,因为每个id都需要字符malloc() 1}}字符串可能很低。

其他更多小问题:

  1. NULL可以返回F[0].id = "F1";,您应该检查一下。

  2. 在您问题的代码中,strcpy(F[0].id, "F1");应为malloc()或类似,否则您将失去对malloc()编辑的内存的引用。< / p>

  3. 您不需要也不应该在C中投出sizeof(char)的回报。

  4. 根据定义,
  5. 1始终为F[0].dim[0].L = 1;,因此您可以将其排除在外。

  6. 对于你评论中的问题:

      

    F[0].dim->L = 1; vs dim[0]怎么样?

    这两个是等价的,在这里。使用下标运算符dim会自动为您解除引用.,因此您可以使用dim[n]运算符来获取元素(*(dim + n)等效于{{1}在C)。如果没有[0]dim是一个直指针,那么您将使用->运算符。显然,当您想要访问数组中的其他元素时,第一个表单会更方便。对于其他人,您必须将F[0].dim[1].L = 1;替换为(F[0].dim + 1)->L = 1;或类似内容,才能使用->运算符,这会导致不必要的错综复杂。