0

構造体の配列を動的に割り当てて操作を実行しようとしていますが、セグメンテーション違反が発生し続けています。誰かが私を助けることができますか?

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

void *malloc(size_t size);

typedef struct {
  double x;
  double y;
} coords;

struct figure {
  char fig_name[128];
  int coordcount, size_tracker;
  coords *pointer;
} fig;

void init_fig(int n, struct figure **point)
{
  printf("%u\n", sizeof(coords));
  point[n]->pointer = malloc(sizeof(coords) * 20);  <-------SEGFAULT
  if (point[n]->pointer == NULL){
    exit(-1);
  }
  point[n]->pointer[19].x = 2;
  point[n]->pointer[0].x = 1;
  point[n]->pointer[0].y = 2;
  point[n]->pointer[7].x = 100;
}

int main()
{
  int numfigs = 1;
  struct figure * point;
  point = malloc(sizeof(struct figure) * 16);
  point = &fig;
  point[1].coordcount = 1;
  init_fig(numfigs, &point);
  return 0;
}

最初のセグメンテーション違反が発生した場所にラベルを付けました(dddを使用)。私が得られないのは、メインでpoint [1]を操作できるが、他の関数では操作できないということです。

4

4 に答える 4

1

@MaximSkurydinに同意します。それでも、あなたの間違いについてもう少し詳しく説明したいと思います。

あなたのものを読むことはあなたが渡すパラメータが実際にはへのポインタの配列であるinit_figと仮定します。そして、この関数はその'番目の要素にアクセスします。struct figure **pointstruct figuren

しかし、あなたmainは何か他のことをします。の配列を 割り当て、struct figure変数pointはその頭を指します。次に、このローカル変数のアドレスを取得して、を呼び出しますinit_fig

ここに問題があります。init_figポインタの配列を渡すことを前提としていますが、実際には、この「配列」は単一の要素、つまりpointで宣言されたローカル変数のみで構成されていmainます。

編集:

これを正しく行う方法。

  1. そのままmainにして、修正しますinit_fig

これは、実際には構造体の配列があることを意味しfigureます。手段-結果として生じる構造体の配列として解釈される単一のメモリブロック。

void init_fig(int n, struct figure *point)
{
  printf("%u\n", sizeof(coords));
  point[n].pointer = malloc(sizeof(coords) * 20);  <-------SEGFAULT
  if (point[n].pointer == NULL){
    exit(-1);
  }
  point[n].pointer[19].x = 2;
  point[n].pointer[0].x = 1;
  point[n].pointer[0].y = 2;
  point[n].pointer[7].x = 100;
}
  1. そのままにしておきinit_figます。修正main

これは、実際にはポインタの配列を割り当てる必要があることを意味します。そのようなすべてのポインタは、割り当てられたpoint構造体を指す必要があります。

int main()
{
  int numfigs = 1;
  struct figure ** point;
  point = malloc(sizeof(struct figure*) * 16);

  for (i = 0; i < 16; i++)
    point[i] = malloc(sizeof(struct figure));

  point[1].coordcount = 1;
  init_fig(numfigs, &point);
  return 0;
}
于 2012-11-03T11:25:36.577 に答える
0

メモリを割り当ててポインタを格納しますpointが、割り当てるときにそのポインタを忘れてしまいます&fig

point = malloc(sizeof(struct figure) * 16);
point = &fig;

だから、あなたは本質的に書き込もうとしているのですがfig[1]、それは意味がありません。

于 2012-11-03T11:22:35.460 に答える
0
  struct figure * point;
  point = malloc(sizeof(struct figure) * 16);

ここでのポイントは、ヒープ内の16の構造体のメモリを指すポインタですが、次の行でこれを実行しました

  point = &fig;

そのため、メモリリークが発生し、ポイントが割り当てられた領域をポイントしなくなります

また、init_figこのようにする必要があります

void init_fig(int n, struct figure **point)

それはセグメンテーション違反の問題です

于 2012-11-03T11:25:00.213 に答える
0

この行を削除しますpoint = &fig;

関数を変更します。

void init_fig(int n, struct figure *point)
{
  ...
  point[n].pointer = (coords*) malloc(sizeof(coords) * 20);
  ...
}

ポインタの配列ではなく、構造体の配列を渡す必要があるためです。

また、init_fig関数に3番目のパラメーターを追加して、作成するポイントの配列のサイズを渡すことができるようにします。好き :

void init_fig(int n, struct figure *point, int size)
    {
      ...
      point[n].pointer = (coords*) malloc(sizeof(coords) * size);
      ...
    }

したがって、関数をより再利用可能にします。

その関数の呼び出しも変更します。

init_fig(numfigs, &point); to init_fig(numfigs, point);
于 2012-11-03T11:28:01.900 に答える